box-sizing
属性可以使构建 CSS 布局变得更容易,也更直观。 它对开发人员来说太有帮助了,以至于我们在 CSS-Tricks 每年 2 月都会 庆祝国际盒子大小意识日。
但是,为什么它如此有用且受欢迎,以至于拥有自己的网络节日? 现在让我们来了解一些 CSS 历史。
盒子模型历史
从 CSS 诞生之日起,盒子模型 默认情况下一直是这样工作的
宽度 + 内边距 + 边框 = 元素盒子实际可见/渲染宽度
高度 + 内边距 + 边框 = 元素盒子实际可见/渲染高度
这可能有点违反直觉,因为您为元素设置的宽度和高度,一旦您开始向元素添加内边距和边框,就会失效。
在网页设计早期,Internet Explorer 的早期版本(<= IE6)在“怪异模式”下以不同的方式处理盒子模型。 “怪异”盒子模型的工作方式如下: 宽度 = 元素盒子实际可见/渲染宽度 高度 = 元素盒子实际可见/渲染高度 边框和内边距值被移到元素盒子的内部,缩减盒子的宽度/高度,而不是扩展它。
有些人更喜欢这种对盒子模型的“怪异”解释,并认为它更直观。 这是一个有效的观点。 拥有与您在 CSS 中声明的不同的盒子实际可见宽度,确实有点令人费解。
但是,在固定宽度设计的时代,一旦您理解了默认盒子模型,它就不是特别复杂。 您可以进行一些算术运算,弄清楚需要从元素的声明宽度或高度中裁剪掉多少像素才能容纳它的内边距和边框。 当今开发人员的问题是,这些绝对像素长度不能转换为响应式设计,因此相同的数学运算不再适用。
随着响应式设计(或曾经被称为“流体”或“液体”布局)开始流行起来,开发人员和设计师希望对盒子模型进行更新。 著名的设计师 Jon Hicks 以其出色的流体宽度设计而闻名,他在我们 2008 年发布的 CSS 愿望清单 中谈到了这个主题
我想要一个不同的盒子模型! 我觉得内边距和边框会增加对象的宽度很奇怪,我真的很想能够为像 textarea 这样的元素设置 100% 宽度和 3px 内边距,而不必担心它会对布局造成什么影响。 也许可以像 padding-inside 这样添加一个新的选择器?
同样,我希望能够为元素指定 100% 宽度,减去一个固定的宽度。 这在使用表单元素创建流体设计时非常有用!
box-sizing
现在的 当 CSS3 中引入 box-sizing
属性时,这些愿望得以实现。 尽管 box-sizing
有三个可能的值(content-box
、padding-box
和 border-box
),但最常用的值是 border-box
。
如今,所有浏览器当前版本都使用最初的“宽度或高度 + 内边距 + 边框 = 实际宽度或高度”盒子模型。 借助 box-sizing: border-box;
,我们可以将盒子模型更改为曾经的“怪异”方式,即元素的指定宽度和高度不受内边距或边框的影响。 这在响应式设计中被证明非常有用,因此它已成为重置样式的一部分。
此时,您可能在问自己,“难道旧 IE 做了什么正确的事情?” 很多人都这么认为。
演示
此演示展示了 border-box
如何帮助使响应式布局更易于管理。 父级 div
的宽度为 50%,它有 3 个子元素,它们具有不同的宽度、内边距和外边距。 点击 border-box
按钮,将所有子元素正确地放置到父元素中。
查看 CodePen 上的 盒子大小布局演示,由 CSS-Tricks (@css-tricks) 创建。
box-sizing
重置方法
良好、更好以及(可能)最佳的 border-box
重置
“旧”的 最早的 box-sizing: border-box;
重置看起来像这样
* {
box-sizing: border-box;
}
这效果很好,但它忽略了伪元素,这可能会导致一些意想不到的结果。 很快出现了一种改进的重置,它涵盖了伪元素
通用盒子大小
*, *:before, *:after {
box-sizing: border-box;
}
此方法也选择了伪元素,提高了 border-box
的规范化效果。 但是,*
选择器使得开发人员很难在其他 CSS 中使用 content-box
或 padding-box
。 这就引出了目前最佳实践的领先者
带继承的通用盒子大小
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
此重置比它的前辈提供了更多的灵活性——您可以根据需要使用 content-box
或 padding-box
(在支持的情况下),而无需担心通用选择器会覆盖您的 CSS。 我们在 “继承 box-sizing
可能略好于最佳实践” 中对该技术及其背后的原因进行了更深入的探讨。 它可能的一个缺点是,box-sizing
通常不会被继承,因此它是专门的行为,与您通常放在重置中的内容略有不同。
供应商前缀
所有现代浏览器都支持无前缀的 box-sizing: border-box;
,因此对供应商前缀的需求正在下降。 但是,如果您需要支持旧版本的 Safari (< 5.1)、Chrome (< 10) 和 Firefox (< 29),您应该包含 -webkit
和 -moz
前缀,如下所示
html {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*, *:before, *:after {
-webkit-box-sizing: inherit;
-moz-box-sizing: inherit;
box-sizing: inherit;
}
已知问题
box-sizing: border-box;
在所有主要浏览器当前版本中都受支持。 不常用的 padding-box
目前仅在 Firefox 中受支持。 我们的 box-sizing
年鉴条目中提供了有关浏览器支持的更多全面信息。
旧版 Internet Explorer(8 及更早版本)存在一些问题。IE 8 无法识别带有 `min/max-width` 或 `min/max-height` 属性的元素的 `border-box`(以前 Firefox 也存在此问题,但已在 2012 年修复)。IE 7 及更早版本完全无法识别 `box-sizing`,但有一个 polyfill 可以帮助解决。
完美的条目!谢谢!
很棒的有用教程。
不错,不知道这在 IE8 中也能用 - 因此它实际上可用;)
与 “装饰性” CSS3 属性(如文字阴影或盒子阴影)不同,`box-sizing` 会完全破坏您的设计,如果浏览器无法识别它。
别提 IE8,我讨厌它。
我也是。我讨厌 IE 版本。不幸的是,在我的国家,人们在 10 年后才开始使用 IE6。
确实如此。因此,请确保您非常了解您的受众。
很棒的教程,我见过的关于此主题的最佳教程。
为了更清楚,你能更改这行代码吗…?
“高度 + 内边距 + 边框 = 盒子的实际可见/渲染宽度”
我认为它应该写成 - 盒子的渲染 “高度”。
如果您在为支持方向更改的设备(如 iPhone)设计布局,这是一个很棒的属性。
您好,
我的解决方案是:永远不要使用内边距。当您为内部元素设置外边距时,您可以获得相同(视觉)效果。通过这样做,所有内容都将被正确计算和处理。
如果您在内部有多个元素,并且不想为所有元素设置外边距,那么将它们分组到另一个嵌套的 `div` 中,并为这个 `div` 设置外边距,这样父元素将获得内边距。
示例
当然,这会增加更多代码,但它在所有浏览器中以及即使在怪异模式下也尽可能安全。
但是您如何用 `textarea` 示例做到这一点?
Michael,很有趣的想法,但是,这不会影响背景吗?内边距允许显示更多背景,而外边距会直接切掉背景。我想在内部元素为 100% 内容的情况下我可以处理一些情况。
我认为我们可以使用这个
和
#parent {width:35%; padding:15%; border:3px; }
#paddingholder { padding:5%; border:2px; }
#content { width:100%; height:100px; }
这是我一直让我困扰的事情。
从学习 CSS/HTML 的一开始,我一直认为将添加的内边距放在盒子内部而不是外部是合乎逻辑的。直到今天它仍然让我感到沮丧。
我也是,我绝对认为内边距应该属于元素内部,这根本没有道理……
IE 做对的一件事,规范却做错了……人生就是这样。
你简直让我大开眼界,伙计。
*轰!*
很棒的文章!我来自巴西,我已经关注你的作品一段时间了,我总是在你那里学到新东西,恭喜你。
奇怪的是,我刚刚自己做了一些相关的工作!在创建 Firefox 扩展时,我使用了一个不错的流畅布局,以便我的部分无论浏览器大小如何都能正常显示。但是,我还想要一个非常漂亮的“Facebook 风格”边框,带有 rgba 颜色,这样它们就可以是透明的。
如果您在元素上设置 `background-color` 并应用边框,它将不会是透明的,因为边框在 *技术上* 位于内容的顶部。使用 `border-box` 和 `background-clip` 的组合,我设法轻松地获得了想要的效果!
应该发布一个到我测试的链接的…我表示歉意!
http://www.devseo.co.uk/examples/facebook-style-overlay-css/
我想我从未真正这么想过。如果你考虑表格中的单元格内边距,它以前就是这样工作的,对吧?内边距会缩小单元格,而不是添加到外部。
我得同意上面 Jason 的说法,并说你绝对让我大开眼界。我脸上露出了大大的笑容,因为我是个大呆子,发现这件事非常有趣。
当我创建一个具有特定大小的盒子时,总是会一次又一次地困扰我,但在设置内边距和一些边框后,盒子的尺寸完全不同。我挠头了好几次,直到我自己做了一些实验才发现内边距 + 边框是造成这种情况的原因。
尽管如此,这是一个很棒的解释。
您还可以使用 `display: table` 将项目置于 `border-box` 大小模式。
哈哈,你好 AJ?Egghead 那边怎么样?真随机。
关于主题:如果您必须选择一个盒子模型,W3 盒子模型比 IE 盒子模型更通用。当那些甚至没有读过规范的人仅仅因为 W3 模型不太直观而认为它很糟糕时,这让我很恼火。
现在我们有了可用的替代盒子大小,我们得到了两全其美。对于标准模式下的 IE6/7,您可以使用 CSS 表达式将它们调整一致。
我猜这个属性很快就会扩展 - 我可以想到其他盒子大小方法,就像 `border-box` 一样,在特殊情况下会很有用。一个用于指示块元素占用它所能占用的所有高度(就像块元素占用它所能占用的所有宽度一样)的值可能会非常有用。
你没有得到任何好主题可以写..对吗,Chris?
我发现,如果您想使用固定大小的页眉和页脚,并将滚动内容插入页面(使用 `overflow-y: scroll`),则 `border-box` 大小几乎是必需的。这似乎是使内容及其所有父级高度为 100%,并具有固定顶部和底部内边距的唯一方法。
非常棒,很有用。它在 IE 8 中很有效,希望在 IE 9 中也能使用。
所有这些 CSS3 的好处,但仍然没有那么实用,最终出现了一个可以真正帮助设计的属性。
目前,“实用”的 CSS3 想法有点不切实际。实际上 - 我们正在接近,但如果您正在设计一个网站,并且有相当数量的流量来自不支持 CSS3 的浏览器,您不会希望您的网站依赖于它。
顺便说一下,我相信 IE9 将非常符合标准。
“`border-box`” 必须记住这个,很棒的技巧。LT
这绝对值得知道。我每次做新设计时都会遇到这个问题。我一直很喜欢评论表单上面那种 3 列式的输入框,但是由于这个问题,在我的个人网站的最新设计中,我回到了评论表单的标准布局。虽然我的网站不是流体宽度(尚未),但自从他们添加了 2.8 或更高版本的那个很酷的新回复功能后,评论一直是流体。我很快就会再次查看这篇文章。
这是 W3C 犯过的最大错误之一,在 1997 年,超过 95% 的浏览器份额被使用盒子大小模型(怪异模型)的浏览器或根本不理解这些 CSS 的浏览器占据。W3C 应该在此时更改规范以反映现实(而非理论),并添加一个新属性:`inner-padding`。
关于 box-sizing 和 border-box,
它也可以在 JQuery 和传统 JS 中使用吗?
[标识符].style.boxSizing
和
[标识符].style.borderBox
谢谢...
当我第一次看到这篇讨论 Facebook 受众数据偏差 17,000 倍的文章时,我得出的结论是,CSS Trick 的常客应该查看
这个!http://hubpages.com/hub/Lies-Damned-Lies-Statistics-ComScores-Facebook-Audience-Claims-Are-Wrong-By-A-Factor-Of-17-000 据 ComScore 统计,
普通 Facebook 用户每天在线时间只有半秒!真的吗!
好文章。
非常有用的文章!这将非常帮助我。谢谢!
嘿,我真的很感谢这个合法的技巧。
优秀的简短教程。我已经厌倦了声明这么多不同的值来修复填充和边框。
谢谢!
“但是,IE 9 即将发布,很快就不再是问题了,”
除了 IE9 无法在 XP 上运行,对于某些用户来说,这意味着不仅要获得新的浏览器,还要获得新电脑。
IE9 的发布对于 Web 开发人员来说并不是灵丹妙药。IE7 将成为新的 IE6。然后是 IE8。而且让我们面对现实吧,很多开发人员在未来几年内仍将与 IE6 打交道(尤其是在企业领域)。
IE7 的消亡速度比 IE6 更快。即使它确实成为了“新的 IE6”,它也不会是另一个“IE6”。
人们正在慢慢升级电脑,这正在稳步淘汰旧版本的 IE。
我认为没有人会为了专门运行某个浏览器而购买新电脑,但如果大多数运行 Vista 和 Win7 的电脑都升级到 IE9,我们就可以放心,额外 15%+ 的用户能够使用 CSS3。当然,这不会在一夜之间发生,但 IE9 的使用份额将稳步每月增长。
IE9 可能不是灵丹妙药,但我认为它至少可以算作一把毒匕首。
这很有趣。我敢肯定这是真的……你有没有看到支持这一观点的数据?
http://marketshare.hitslink.com/browser-market-share.aspx?qprid=3
https://w3schools.org.cn/browsers/browsers_explorer.asp
http://www.w3counter.com/trends
http://www.xmarks.com/topic/browser_statistics
没有“全球”统计数据,但上面提到的网站显示了一些趋势。
非常酷。
在我看来,它们表明它们的下跌速度大致相同,但 IE 7 的份额仍然更大。因此,如果它们保持甚至下降的速率,IE 7 将始终拥有更高的百分比。如果 IE 6 再次超过 IE 7,那就太疯狂了。
有趣,但不是跨浏览器的 :(
你的演示代码不适用于
不适用于包含
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”
有史以来最好的文章……
这始终是我对 CSS 布局最大的抱怨——当然,除了迎合所有 Internet Explorer 的怪癖之外。具有讽刺意味的是,IE 实际上曾经以 border-box 的方式实现它。
感谢这篇文章。我将从现在开始在我的所有网站中引入它——去死吧 IE 7。我说了吗?我的意思是,我们会为 IE 找到一个糟糕的解决方法,将其放在自己的样式表中或其他地方。
嘿,为什么在“糟糕尝试”中你不直接使用 3% 的填充,并使用轮廓代替边框呢?
感谢这篇文章,它确实帮助我了解了我一直想知道的东西。
我想要一个“box-sizing: margin-box”,然后像这样的技巧将不再需要。
有没有 W3C 的人听到?
.navigation_main ul li a {
background-color: #FFFFFF;
border-radius: 5px 5px 0 0;
color: #003366;
font-size: 13px;
margin: 1.2px;
padding: 5px;
}
在这段代码中,填充和边距只在 Chrome 和 Firefox 中起作用,我需要在 IE 9 中让这段代码生效……但出现了对齐问题,请帮助我解决这个问题。
http://jsfiddle.net/nsrau/ptt58/
SubtractJS 对盒子模型提供了不同的看法。
SubtractJS 可以填充屏幕边缘或任何定位为相对或绝对的盒子。它也可以填充整个盒子。
它调整内容的大小,使内容加上填充、边框和边距完全填充包含盒子。
它非常适合创建固定标题、页脚或边缘,以及精确填充绝对或相对定位的元素。
只是一个小的补充。
请注意,伪元素 ::after 和 ::before 似乎不遵循通用选择器中的规则
* {
box-sizing: border-box;
}
所以,使它们看起来符合你的要求的最佳方法是在 ::after/before 声明本身中重复 box-sizing 规则。
所以,如果我理解错误,请纠正我,我认为我听到的是你更喜欢 Microsoft 盒子模型,并且希望所有浏览器一直以来都默认以这种方式实现它。
我同意。
该代码在 Firefox 控制台中抛出警告(css 警告)
box-sizing:border-box;
这是 Firefox 的错误吗?嗨 Chris,
你推荐什么方法来解决 IE7 问题 - 你知道有什么轻量级 PolyFill 吗?
欢呼!
Dan
就我个人而言,如果我必须支持 IE 7,我甚至不会尝试。旧的方式更难思考,但并不难太多。用 Polyfill(更多代码)来惩罚旧浏览器感觉不太对。
感谢你的快速回复,Chris。
我已经习惯了使用 border-box,甚至没有考虑过 IE7,但我目前正在为的客户支持它。我考虑过使用 Polyfill,但你说得对,这有点过头了。
一如既往的好分享,感谢 Chris。
对于 IE,box-sizing 属性取决于 IE 文档模式,它在“IE8 标准模式”及更高版本中有效。所以它也将在 IE8 浏览器中工作,如果文档模式是“IE8 标准模式”。