今天是 2 月 1 日,我决定将这一天宣布为 **国际盒子大小意识日**。 为了纪念,你猜对了,最谦虚、最默默无闻,但最棒、最有用的 CSS 属性:box-sizing
。
这个日期对应于 Paul Irish 的帖子,他在帖子中介绍了在页面上的每个元素上使用它的概念。 我们也曾 在 CSS-Tricks 上 多次讨论过它。
这是它在所有荣耀中的样子
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
box-sizing
属性通常不会级联,而您将强制它级联,但这使得在组件级别覆盖它变得容易得多。box-sizing
的默认值为 content-box
,这是我们在这里要覆盖的。 还有一个 padding-box
值,但...如果你问我,它有点没用。 我们很快就会知道这意味着什么。
请注意,我们使用 *
选择器来选择所有元素,并使伪元素使用相同的模型,否则它们将不会被 *
选择器单独选择。
这是浏览器支持情况。“-” =“此版本及以下”。“+” =“此版本及以上”。
*, *:before, *:after {
/* Chrome 9-, Safari 5-, iOS 4.2-, Android 3-, Blackberry 7- */
-webkit-box-sizing: border-box;
/* Firefox (desktop or Android) 28- */
-moz-box-sizing: border-box;
/* Firefox 29+, IE 8+, Chrome 10+, Safari 5.1+, Opera 9.5+, iOS 5+, Opera Mini Anything, Blackberry 10+, Android 4+ */
box-sizing: border-box;
}
在不久的将来,我们根本不需要任何前缀,但我喜欢把这种事情留给 Autoprefixer。
为什么如此激动?!
它使处理盒子变得超级超级容易。
当你设置元素的宽度时,那就是它的宽度。 如果你将宽度设置为 25%,它将占据其父元素可用水平空间的 1/4。 就这样。
情况并不总是这样。 使用默认的盒子大小,只要元素应用了填充或边框,实际呈现的宽度就会比你设置的宽度更宽。
实际宽度 = 宽度 + 左边框 + 右边框 + 左填充 + 右填充
数学已经足够糟糕了,但当与百分比(或任何混合单位)结合时,结果无法在脑中计算出来,更重要的是,最终会变成一个你无法处理的无用数字。
你可以这样想:使用 box-sizing: border-box
,填充和边框 * 向内压 *,而不是扩展盒子。 结果是一个与你设置的宽度完全相同的盒子,你可以依靠它。
列是一个 特别有用的案例,但这在所有时候都非常有用,并成为那些 让 CSS 开发变得更好 的事情之一。
记得阅读 Paul 的原始帖子,它涵盖了更多内容,比如性能(不用担心)、jQuery(不用担心)和第三方内容(很容易修复)。
祝 **国际盒子大小意识日** 快乐! 也许明年我们可以组织起来,都戴上 时髦的方形太阳镜 等等。
我喜欢这个。 我已经使用它一段时间了,它是 CSS 中我最喜欢的部分之一。 创建一个小的 Sass 混合,你甚至不需要记住所有前缀。
然后
@include box-sizing
;如果你不需要将其应用于链接到样式表的页面上的所有内容,这将更有用。
这完全有效! 只是几点说明...
或者,只需使用一个为你进行前缀处理的预处理器,这有助于保持代码简洁! 我推荐 Prepros。
@chris 我不知道 Compass 居然有它的混合。 可能应该花些时间了解一下它们提供了什么。 我只使用过过渡和转换混合。
我还需要更多地了解 @extend 属性,它看起来很棒!
我在让 Autoprefixer 与 CodeKit 配合使用时遇到了一些问题。 我会继续尝试使用它。
谢谢 Chris! :)
我和 Chris 在这一点上是一致的。 通配符选择器非常适合盒子大小,尤其是在响应式设计使布局都变得百分比化的情况下。
如果不需要重复,混合有什么用呢? 我发现混合在需要多次使用的属性并且需要供应商前缀的情况下最有用。 通配符 * 可以像本文前面所示那样处理所有事情。
*,*:before,*:after{box-sizing: border-box;}
边框盒子很好,但内容盒子仍然有用。 这里有一个有用的情况:你想要一个流体容器,它居中并且不会增长超过 1000 像素,如果浏览器窗口小于 1000 像素,它仍然有填充。
我不确定我是否完全理解。 简单的演示。 盒子大小如何影响你执行此操作的能力?
只是能够在这两者之间切换很好。 在我的示例中,填充就像第二个边距,因为我使用边距来使容器居中。
在我的情况下,我想要一个容器来放置元素,它不会增长超过 1000 像素。 由于我想使用两侧的百分比间隙,因此使用边框盒子来使内部区域不超过 1000 像素会更难。
以下是用 边框盒子 执行与上面内容盒子示例相同操作的示例。
我必须使用 calc 将填充添加到最大宽度。 现在,当你的浏览器宽度大于 1048 像素时,测量 DIV 内部的 P 元素,它正好是 1000 像素。
十年前,当我第一次开始探索 HTML 和 CSS 时,我还是个孩子(大约 12 岁),并且习惯在 Windows ME 上使用 IE(是的,我知道,你笑了)。 :D
然后,我发现了“正常”的 CSS 内容(使用 Firefox),并开始学习真正的盒子模型。 我一直很怀念 IE 的唯一一点是它对模型的错误解释(我的意思是,IE6 以前会按照
border-box
的方式做所有事情)。 当border-box
出来时,我很高兴我的"width: 100%"
概念又回来了。 :)为了明确起见,这是一个小小的误解。 IE6 * 之前 * 是这样的,但 IE6 是正常的盒子模型, * 除非 * 在怪异模式下,怪异模式由诸如不正确或缺少 DOCTYPE 之类的东西触发。
维基百科上的这篇文章 对其解释得很好。
传统上,建议使用更强大的重置,比如 Eric Meyer 的重置,因为性能原因。
如果你已经在使用通配符选择器来应用
box-sizing
,那么有没有理由不使用相同的声明来进行重置?这是我的首选重置。
你应该切换到 normalize。 通用重置太老派了。
它并没有“老派”。 不同的概念,不同的目标。 个人喜好。
个人喜好,没错。但是,传统上来说,通用重置确实已经“过时”了。只要有效,使用“过时”的方法并无不妥,但未来你可能会看到更多使用 normalize 的情况,因为 normalize 是一种更精细的方法,不需要太多额外的手动操作。
最终,可以说 normalize 是一种更 DRY 的方法。当然,normalize 只是一个指南。每个人都可以有自己的“normalize”流程,而且预处理器最近做得很好,允许这种自定义。
标准盒模型是 W3C 犯下的最糟糕的错误之一。
微软偶尔会正确地认为,设计师希望调整*容器*的大小,而不是内容。
因此,IE6-7 甚至不支持 border-box 大小调整(原生——可以通过 CSS 表达式实现变通方法),除非在怪异模式下,而怪异模式永远不应该使用。永远。
希望明年是国际 FlexBox 意识日。
我希望我早点知道这种调整大小的方法。我必须做很多嵌套元素才能实现这一点——这将真正清理我的部分代码。
作为一个娃娃脸的网页设计师,这确实有一些好处;自从一年前开始学习 CSS 以来,我从未用过旧的
box-sizing
值,因为各浏览器都提供了良好的支持。这使得学习基于浮动的布局变得容易得多,也避免了许多潜在的挫折。Bootstrap 3 和 Foundation 5 现在都默认在每个元素上使用
box-sizing: border-box
。在我看来,这基本上就确定了它是一种最佳实践。我想知道,Mozilla 什么时候会放弃前缀。从 2004 年(!)开始,就一直在讨论放弃它:https://bugzilla.mozilla.org/show_bug.cgi?id=243412
他们已经放弃了,据我所知,在 29 版本中将会稳定。
很棒的帖子!我已经阅读了几篇博客文章,了解了
box-sizing:border-box
,但我实际上是在阅读这篇文章后,在今晚创建了一个 CodePen。它真的很棒!我记得几年前刚开始学习 html/css 的时候,我根本不知道 border-box 或 calc。要创建一个占页面特定百分比且带边框的盒子几乎是不可能的,你必须对 html/css 做一些很奇怪的事情,或者不使用边框,或者使用 JavaScript,而我当时不太擅长 JavaScript。我很高兴这个属性存在,它直观得多。
在我学习了 box-sizing
border-box
之后。但我从老设计师那里得到了一个愚蠢的论点(他们仍然遵循table tr td
这种方法,对于 IE-6/6- 版本来说,很难分别调整布局的大小。因此,最好对所有内容使用
content-box
,而不是重置!“——但是,我认为对于那些复制 PSD 网页模板的人来说,使用
content-box
是正确的,因为他们使用 Photoshop 切片!”如果你要为 IE 5 及以下版本设计,这将是最不值得担心的问题。
我在 Paul 发布原始文章的几天前偶然发现了这段代码片段的奇妙好处:几天前,我一直都在使用它。
正如 MaxArt 在上面提到的,IE6 和 IE7 不支持此 CSS,这对于大多数人来说可能不是问题。
当我还在使用 LESS 的时候,我不得不支持 IE7 的一个项目。因此,我在 CodePen 上写了一个简单的 mixin,通过使用添加到 HTML 中的条件类来创建 IE6-7 的回退。
我现在使用 Sass,从 2012 年年中就开始使用,因此我决定使用 Sass 重构该 mixin,它也在 CodePen 上。
我还 写了一篇文章,介绍了它在我的博客上如何工作,这篇文章是去年年底发布的。
该 mixin 也包含在我的 Sass 库中——Sassifaction
真是太棒了!所有关于百分比的繁琐操作现在都成为历史了!谢谢!!!
伪元素名称之前的星号(
*
)是多余的。*, :before, :after
就足够了。顺便说一下,在 Paul 写这篇文章的时候,
box-sizing
实际上还不能全局使用,因为 Firefox 有一个 错误,导致在与box-sizing: border-box
结合使用时,min-height
/max-height
的计算结果不正确。从那时起,这个错误在 2012 年 11 月发布的 Firefox 17 中已经被修复,现在可以全局使用box-sizing: border-box
了。选择器命名确实如此!星号实际上代表“任何元素”,而什么都不写也代表“任何元素”。就像
*.class
与.class
相同,即使在特异性方面也是如此,因为*
没有特异性。(测试用例)。关于 min- max- 问题的提醒也很不错。我不确定这是否会让它无法使用,但它确实需要引起注意。
直到最近,我实际上只使用它来使响应式表单正常运行,当工作中有人建议全局使用它时,我感到有点震惊。现在,它已经包含在我每个项目中的重置的一部分中。
太棒了!我以前不知道!这会让生活变得轻松很多。谢谢 Chris!(以及最初的 Paul)!
我刚接触“网页开发”,说实话,整件事似乎比它应该的要难得多;这个小技巧绝对让我的网页开发生涯轻松了许多。非常感谢你。
我在一些项目中使用了 JavaScript 来解决这类问题,并嵌套了 div 来覆盖超出边界的內容。谢谢你的信息!这对我很有用!;)
我努力让每一天都成为国际盒模型日。我无法用言语表达对它的赞美。每次我从公司中的一位设计师那里拿到一个需要修复的布局时,添加它都是我做的第一个修复。神奇的是,东西就对齐了。
为什么我没有使用 box-sizing?!
我个人讨厌重置,但这行代码是我首先应用到所有内容中的代码。自从我开始使用它以来,跨浏览器的問題减少了很多。它可能为我节省了数百小时的故障排除时间,这些问题都是 IE 与其他浏览器之间的差异造成的。
再一次,我只需要随意访问这个网站,就能学习到一些非常有用的东西。谢谢 Chris(以及最初的 Paul)!
我很惊讶以前有人没有听说过这个……这让我大吃一惊。
同意!对于 Chris 这样拥有广泛受众的人来说,这是一个很好的理由,可以继续写关于这些事情的博客。有时我们过于关注未来和当下,而忘记了跟上步伐可能有多么困难。有时,如果被某个项目牵扯六个月,没有时间跟上,就意味着你会错过像这样的重要东西。
我是唯一一个喜欢保留浏览器默认的 content-box 并只在需要时才应用 border-box 的人吗?这样我就不需要在使用 content-box 的时候在 CSS 中设置回 content-box。两种盒子模型在特定情况下都有意义,而且在页面上的大多数元素上它们没有区别。
无论如何,只在需要的地方应用 border-box 对我来说感觉更简洁,如果其他人喜欢其他方式也没关系。
我知道你的想法,但一旦你切换到通用选择器,你会发现它在很多地方都派上了用场。对任何响应式设计来说尤其如此。
由于副作用很少,这可以减少一项计算。它可以正常工作。
在 CSS 世界中,Border Box 是我最好的朋友。
每次意识到“天啊,IE6 在盒子模型方面真的做对了”的时候,我的心都会稍微碎裂一点。
无论如何,这是事实。
为什么?当时 IE6 是最好的,而且是现代浏览器中的佼佼者。
不是 IE6,而是 IE5.5 及更早版本。IE6 只有在怪异模式下才会这样做(我认为这是故意的,是为了向 IE5.5 盒子模型兼容)。除了某些(不可否认的重大)浮动/边距错误和其他布局问题之外,IE6 的盒子模型渲染得很好。
IE6 发布时没有任何问题。它发布时远远领先于其他浏览器。只是他们在垄断地位受到威胁之前停止了创新。
这会让我的生活变得容易很多。谢谢 Chris!
毫无疑问,这段代码在我的默认 CSS 中。终于有人为我真正关心的事情提高了意识!(或许有点开玩笑,但仍然)
谢谢,我之前都不知道这个东西的存在……谢谢。
谢谢 Chris 分享这篇重要的文章。几周前,我遇到过这个问题,当时一个客户需要一个固定宽度为 300px 的盒子,我在这个盒子应用了边框和内边距后,我注意到盒子的宽度超过了 300px。在 Firebug 布局中进一步检查后,我用你提到的公式计算了宽度,结果是 305px。现在使用 box-sizing 比计算宽度要好。谢谢。
应该通知 CSSLint,我不使用这个程序,因为它讨厌使用全局元素来对任何东西进行样式化,而且我不会去加载一个针对每个已知可能未知 HTML 元素的重置文件。我真的很喜欢代码检查工具,我只是希望像这样出色的修复能被包含在其中。
我喜欢 box-sizing。
我发现我会一直把它添加到许多元素中,然后发现了选择器或元素方法(*)。
我承认,当一个元素无法正常工作时,这确实让我很头疼,原因是 box-sizing。但一旦我理解了原因,它就很容易解决(可能是容器等等)。
所以我更喜欢选择所有元素,并进行一个修改来解决一个小问题。
我一直想知道我是否应该这样做 - 现在我会这样做!
请原谅我的无知,但我无法理解为什么你需要 before 和 after 伪元素?
因为全局选择器不会选择它们。
哦,是的,谢谢!
哇!我已经看到这个一段时间了,但我从没费心去弄明白它的意思。现在我知道它能做什么,我就会一直使用它。谢谢。
Sass + Compass
我使用 box-sizing 就好像使用除臭剂一样。
我正在进行的一个项目使用了全局和伪选择器方法。我们一个重要的布局元素在所有浏览器中都无法在 Firefox 中正常渲染。我花了很长时间才找到解决方案(仅仅指定 width: 100%:你会认为这没有必要)。太长时间了,它看起来像是由全局 box-sizing: border-box; 引起的渲染问题。
我认为我一个人不喜欢全局方法。抱歉 Chris(也抱歉 Paul Irish,他也有类似的帖子)。我理解 content-box 模型带来的挫败感(我也经历过那种痛苦),但我认为它带来的问题只出现在每个页面上的少数容器中。对我来说,这不足以证明使用全局选择器来彻底改变整个页面的布局模型。
我发现这对 Button 元素不起作用。
http://codepen.io/NickToye/pen/rCmED