CSS3框大小:margin-box;为什么不?


139

我们为什么没有box-sizing: margin-box;?通常,当我们放入box-sizing: border-box;样式表时,我们实际上是指前者。


例:

假设我有2列的页面布局。这两列的宽度均为50%,但它们看起来有点丑陋,因为没有装订线(中间有缝隙)。下面是CSS:

.col2 {
    width: 50%;
    float: left;
}


要应用装订线,您可能会认为我们可以在两列的第一列中设置合适的边距;像这样的东西:

.col2:first-child {
    margin-right: 24px;
}

但这将使第二列换行,因为以下内容是正确的:

50% + 50% + 24px > 100%

box-sizing: margin-box;可以通过在元素的计算宽度中包括边距来解决此问题。我觉得这很有用,即使没有比有用box-sizing: border-box;


30
“为什么我们没有box-sizing: margin-box;?” 因为尽管水平边距不会崩溃,但这样的主张会严重干扰垂直边距的崩溃。无论如何,如果您想提出一些标准化的建议,Stack Overflow并不是正确的选择。尝试邮件列表。
BoltClock

16
在某些情况下,您可以使用来解决此问题border: xxx solid transparent;,因为边框已包含在中border-box。但这会破坏其他一些东西,例如box-shadow
内森·奥斯曼

28
我们现在是否要解决所有关于“非建设性”标准的问题?这是一个很公平的问题,甚至有一个简单的答案:我们没有,box-sizing: margin-box因为它不适用于保证金倒闭。
thomasrutter

@thomasrutter:一年多以前,在我关闭它时,并没有一个措辞更好的理由。无论如何,“非建设性的”现在消失了(意味着不,我们实际上不再关闭任何非建设性的东西),并且由于整个“我有一个主意,这就是它的工作原理,让我们将其作为一个标准!” 自从上次关闭以来,它已被删除,实际上听起来像是一个实用的“为什么X不能工作?” 题。这仍然是一个令人难以置信的投机性问题(我上面的推理只不过是有根据的猜测),但是我对此不作进一步评论。
BoltClock

为什么不想要一个内部包装纸/ div,如果你想间隔的话:codepen.io/chriscoyier/pen/eGcLw
ashley

Answers:


55

你不能用width: calc(50% - 24px);你的cols吗?然后设置边距。


5
它高度依赖于浏览器。大概在2020年左右,ie15将支持它,并且您也可以在工作中使用它:-(
peterh-恢复莫妮卡2013年

1
在Firefox中似乎运作不佳?(或者我没有做过的其他事情)
Laurengineer

@Morgan Feeney:是的,但是box-sizing没有一个叫做margin-box的值(这是整个问题的重点)。即使现在引入了这样的值,您如何建议将其修补/填充/填充到现有的浏览器中?
BoltClock

是的,但是...专门回答了一个建议使用calc()作为解决方法的答案。
Morgan Feeney

不知道这是否适用于特定示例,但在我们的场景中(如FF 53.0.3),主要不利于使用calc()的行为是与宽度的行为不相似:X%; 从我们可以看到,“ calc”是在初始渲染为静态Xpx时完成的。这意味着,与width:X%不同,calc'ed列不会随容器调整大小而自动调整大小。
Pancho

16

我想我们可以有一个box-sizing: margin-box。css框模型精确显示了框架边距的位置。

存在一些小问题-例如,边距框可能会重叠-但并不难解决。

我认为情况是一样的,我们可以通过overflow-xoverflow-y组合看到,在表格单元格中使用绝对位置的div,将min | max-width | height与框大小结合使用,依此类推。

有些功能是非常简单的功能,而浏览器开发人员根本就不会开发这些功能。

恕我直言,这box-sizing: margin-box是一个非常有用的功能。另一个有用的功能是box-sizing: padding-box,它至少存在于标准中,但未在任何主要浏览器中实现。甚至没有最新的镀铬!


注意:@Oriol的评论:Firefox确实实现了box-sizing:padding-box。但是其他人没有,因此将其从规范中删除。Firefox将在版本50中将其删除。


2
Firefox确实实现了box-sizing: padding-box。但是其他人没有,因此将其从规范中删除。Firefox将在版本50中将其删除。
Oriol

6

顶部的人正在询问有关增加整个宽度(包括填充和边框)的边距的问题。关键是,在使用时,在框外应用了边距,而没有填充和边框border-box

我试图实现这个border-margin想法。我发现,如果使用margin,则可以.last在最后一项中添加的类(使用margin,然后将margin设置为零,或使用:last-child/:last-of-type)。或始终添加相等的边距(类似于上面的填充版本)。

在此处查看示例:http : //codepen.io/mofeenster/pen/Anidc

border-box计算元素的宽度+其填充+边界作为总宽度。因此,如果您有2 divs,它们的宽度为50%,则它们将相邻。如果您8px向其中添加填充,则将有的装订线16px。将其与包装元素(也具有填充)结合使用8px,您将获得一个布局良好的网格,并且始终具有相同的排水沟。

参见以下示例:http : //codepen.io/mofeenster/pen/vGgje

后者是我最喜欢的方法。


4

我敢肯定所有这些都是显而易见的,但是无论如何我都会把它打出来,因为...好吧,我需要练习。以下结果是否会不如以下结果有效box-sizing: margin-box;

.col2 {
    width: 45%;
    height: 90%;
    margin: 5% 2.5%;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
}

http://jsfiddle.net/Fg3hg/

box-sizing用于控制从哪一点开始将填充和边框评估为元素的整体大小。因此,虽然不包括px带有%宽度的边距(通常是这样),但由于不必将填充和边框合并到定义的宽度中,因此计算相对百分比应该更容易。


9
诸如边距框之类的用例是使百分比宽度与像素边距混合。如果您想要两个50%的框之间有1px的边距,则无法以类似值的1%的百分比边距来完成-一些小的屏幕尺寸会将1%舍入为0像素,突然之间您就没有边距了。我们真正需要的是@Slouch显示的更多浏览器对calc()的支持,或flexbox模型。

1
如果这样的话,父容器将小于100px,我希望在那时重新考虑一些设计元素。您还可以使用嵌套元素之类的东西做其他事情,但是,是的,进行变量计算会很不错。如果您喜欢无聊的事情,我想他们会做很多这样的事情。我和他们一起玩,但还不是绝地武士。
Plummer

2
您的建议是解决方法。当您使用复杂的布局时,这不是编写CSS的理想方法。您假设设计师或作者想要在设计中使用百分比。同样不管这个问题如何,即使您使用calc()函数使用像素边距来计算间距,它仍然限制了设计者,因为他们必须预先确定装订线是什么,而不是使用CSS覆盖装订线。
limitlessloop

我不明白你的意思。当前的问题是,包括px和%会导致换行,因为大小计算中不包括边距。元素大小不包括边距,它是您要在元素周围显示的空间。另外,如何margin-box处理多维边距计算?@media断点,max-width并且min-width工作正常。我想margin-box可能会减少一些膨胀,但我也有理由将其视为多余。
Plummer 2014年

为什么没有人提到此边距百分比值是出于某种原因的宽度百分比……与高度或宽度无关。使用父级的宽度。至少可以这样说是很奇怪的..因此,上面的代码不起作用,也不起作用。除非您使高度和宽度相等。
穆罕默德·乌默尔

4

这是因为box-sizing属性是指在计算给定的尺寸特定值(填充,边框)后,元素的大小。“ box-sizing:border-box”设置元素的高度/宽度,并考虑填充和边框宽度。元素的边距范围大于元素本身,这意味着它修改了页面及其周围元素的流程,因此直接改变了元素相对于其同级元素适合其父元素的方式。最终,“边距框”属性值将导致严重问题,并且与直接设置元素的高度/宽度基本相同。


1
我深表歉意,但我不明白通过“边距框”在空间计算中包括填充,边框和边距与通过“边界框”包括填充和边框在概念上有何不同。当然,这只是同一主题的变体?
Pancho

1

Codrops上有几篇很好的文章,涉及页边距和行被迫溢出的影响。他们建议对所有浏览器使用rem或em单位并使用标准化器css将字体大小设置为100%,然后在设置宽度和边距时,只需在注释中添加注释即可轻松跟踪行宽的影响总宽度。将16px转换为1 em是计算目标视口总数的方法。

至少在开发阶段就这样工作,然后,如果您想要“响应式”模板,则可以将宽度转换为%,包括边距宽度。

他们建议使用的另一种通常更简单的方法是content: '';在每个列上使用伪after和the伪列,我发现它们确实很好用。如果您将div类设置为已定义的最后一列(例如end),则可以将该类作为目标,以使其不具有伪后号,或者不具有更宽的伪类。最适合您的布局。

使用这种伪元素方法的额外好处是,它还为您提供了阴影目标,该阴影可以为阅读器监视器上的平面图像提供更多的3d效果和更大的深度。目前,我正在通过放大按钮上使用的效果,“调整”渐变和z-index来对此效果进行实验。



1

也许使用RGBA将边框设置为0%不透明度,并将边框用作边距。


听起来像骇客,但可以胜任。
Morgan Feeney 2014年

如果您不想使用包装器来完成这项工作,这可能会很有用。
limitlessloop

...除非你真的需要一个边界
FrancescoMM

@FrancescoMM-有点“嘈杂”,但是您可以制作一个带有“边距宽度”透明边框(当然也没有边距)的盒子,并在其中放置一个带有要显示宽度的可见边框的盒子(再次没有)保证金)
Pancho

1
我就是无法遵循这种想法。有什么比我说我要1px分开两个盒子,每个盒子要占用50%可用空间更自然的说法吗?那正是margin-box会做的。或忘记边距框并考虑可用空间。不是父容器的50%,而是剩余的50%。没有“计算”,没有“ 5%保证金”,没有这种混乱……
maaartinus

0

使用Box-Sizing时出现有趣的情况体内内容

无内容无边框左右边缘空白不提供任何值这两个框重新计数算法的重新计数百分比

  .body{
    box-sizing: border-box;
    margin:0 3%;
  }

Firefox 57之前的版本也支持box-box大小的padding-box值,尽管该值已从浏览器的规范和更高版本中删除。

因此,甚至没有计划的保证金箱...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.