Another RayJune

完备的 box-sizing border-box

整合了:为什么使用 box-sizing: border-box,什么时候使用,使用它的好处和注意事项,力求完备的效果

问题的出现

我们都知道盒模型的构建(model box):

由内到外依次是 content, padding, margin, border;

也知道关于它的计算方式的黑历史:

标准盒模型的计算方式是:

1
width = content

这样不好吗?十分不好。

因为虽然我们设置的 width/height 直接等于元素的 content 宽高,但是显示出来的元素宽高可是加上了 padding, border 的(margin 可能会因为 BFC 发生 margin collapsing,不好计算,所以我们认为 margin 是元素之外的元素间间距,没有考虑在内):

实际显示的 height/width 情况:

1
width = content + padding * 2 + border * 2 // height 同理

使用起来别扭吗?十分别扭。每次计算宽高都还要在指定 width/height 的基础上加上 padding * 2 + border * 2,简单的情况还好,遇到响应式布局等复杂情况数学老师就真的扎心了。

IE 盒模型的逆袭

因为 IE 盒模型的计算方式是:

1
width = content + padding * 2 + border * 2; // height 同理

所以有了 IE 盒模型的“复古”推崇,leader 再也不用担心我的数学了。

1
2
3
* {
box-sizing: border-box
}

是不是差了什么?:before:after 这两个伪元素呢?(伪元素应该用 :: 表示,但目前 : 的适用性更好,所以这里用 :

1
2
3
4
5
*,
*:before,
*:after {
box-sizing: border-box;
}

可是这样全局设置为 IE 盒模型不完全妥当,因为 box-sizing 属性不会默认继承。

如果你想在哪个元素使用标准和模型计算方式 box-sizing: content-box 时,会发现通配符把它的子元素也同意设置为 box-sizing: border-box 了(比如使用 disqus 时)。

为了应对这种情况我们有了以下终极方案:

1
2
3
4
5
6
7
8
9
html {
box-sizing: border-box;
}

*,
*:before,
*:after {
box-sizing: inherit;
}

其中奥妙,想必读者一看便知。(还是来一行注释把:/* apply a natural box layout model to all elements, but allowing components to change */

通配符只有在类似 .foo > * 这样的情况下会速度很慢,普通状态下的通配符 *h1 等元素一样快。

可能会有人担心通配符 * 的性能问题,这里就要辟谣了:

这便是现在通用的解决方案了,CSS 代码起手式,连 Paul Irish 也表示再也离不开这个 gist 了:https://www.paulirish.com/2012/box-sizing-border-box-ftw/。

border-box 无懈可击吗

当有一个绝妙的解决方案出现的时候,作为一个 web 开发者,千万别忘了兼容性

caniuse 一下,https://caniuse.com/#search=caniuse ,一片飘绿,IE 11 都支持完备。

stackOverFlow 一下: border-box drawback

https://stackoverflow.com/questions/19940459/box-sizing-border-box#answer-19940588

The cons,
IE7 and below have no support, who cares right? Some sadly do.
IE8 and up have only partial support.

https://stackoverflow.com/questions/10722841/box-sizing-border-box-to-border-box-or-not-to-border-box-all-elements#answer-10723334

看来在 < IE8 的浏览器不支持,不过没关系,我们有万能的 polyfill: https://github.com/Schepp/box-sizing-polyfill

总结

css-tricks 甚至特地宣布每年的二月一号为 International box-sizing Awareness Day,表示了对它的认可。

回到最初的话题,box-sizing: border-box 够完备吗?

现在我们可以自信的说:是的,它够完备。

Reference & Thanks

paulirish:
https://www.paulirish.com/2012/box-sizing-border-box-ftw/

css-tricks:
https://css-tricks.com/international-box-sizing-awareness-day/
https://css-tricks.com/box-sizing/

stackoverflow:
https://stackoverflow.com/questions/19940459/box-sizing-border-box
https://stackoverflow.com/questions/10722841/box-sizing-border-box-to-border-box-or-not-to-border-box-all-elements

caniuse:
https://caniuse.com/#search=caniuse

jeremenichelli:
https://jeremenichelli.io/2015/05/why-nobody-knows-about-box-sizing/

谢谢观看,good day :)

文章标题:完备的 box-sizing border-box

文章作者:RayJune

时间地点:下午 17:20,于又玄图书馆

原始链接:https://www.rayjune.me/2018/01/26/border-box-pros&cons/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。