css 盒子模型标准盒和 IE 盒区别
标准盒模型的 width 仅指内容区,padding 和 border 额外增加;IE 盒模型的 width 已包含 padding 和 border,margin 始终在外,可用 box-sizing 在两种模型间切换。
学完这篇,你能一眼看出一个元素的 width 到底包不包含 padding 和 border,并且能用 box-sizing 按需要切换两种盒模型,不再靠反复试数字来调布局。
第一步:先搞清两种盒模型对 width 的定义
两种盒模型的差别只有一句话:width 到底从哪儿量到哪儿。W3C 标准盒模型(content-box)里,width 只等于内容区的宽度,padding 和 border 是「额外加上去」的;IE 盒模型(border-box)里,width 已经包含了 padding 和 border,内容区被它们往里挤。
用公式写清楚:
content-box(标准盒):
元素占位宽度 = width + padding-left + padding-right + border-left + border-right + margin
border-box(IE 盒):
元素占位宽度 = width + margin
内容区宽度 = width - padding-left - padding-right - border-left - border-right
记住关键词:margin 永远在 width 之外,两种模型都一样,这点别搞混。
注意:名字里的「IE 盒」只是历史叫法。现代浏览器里
border-box是标准特性,不是 IE 专属,也不需要用 hack。
第二步:用一组具体数字算一遍
假设一个 div 这样写:
.box {
width: 200px;
padding: 10px;
border: 5px solid #333;
margin: 20px;
box-sizing: content-box; /* 默认值 */
}
在 content-box 下:内容区 200px,元素实际占位宽度 = 200 + 10×2 + 5×2 = 230px,再加上 margin 20×2,整行占 270px。你写 200px,实际画出来是 230px。
把 box-sizing 改成 border-box 后:总占位宽度仍是 200px,内容区被压成 200 − 20 − 10 = 170px,再加上 margin 20×2,整行占 240px。你写多少,看起来就是多少,这就是大家爱用 border-box 的原因。
第三步:用 box-sizing 属性切换
box-sizing 有两个值:content-box(默认,标准盒)和 border-box(IE 盒)。它写在哪个选择器上,就只作用于那个选择器匹配到的元素。
.standard { box-sizing: content-box; }
.ie-box { box-sizing: border-box; }
改完刷新页面即可,不需要加浏览器前缀。box-sizing 不能继承,父元素设了不代表子元素跟着变,所以项目里通常统一全局设置。
第四步:在 Chrome 开发者工具里验证
打开 Chrome,按 F12(或 Ctrl + Shift + I)打开开发者工具,切到「元素(Elements)」面板,用左上角的箭头图标选中目标元素,右侧「样式(Styles)」面板底部会显示一个盒模型示意图,从内到外分别是 content、padding、border、margin,中间数字就是当前值。
想看当前元素到底用的哪种模型,切到「计算样式(Computed)」面板,在过滤框输入 box-sizing 就能看到实际生效值。这一步很值得养成习惯:调布局对不上数时,先看一眼这个图,比猜快得多。
第五步:项目里统一设置成 border-box
绝大多数项目会在全局样式文件顶部加一段重置,让所有元素都用 IE 盒模型:
*,
*::before,
*::after {
box-sizing: border-box;
}
写 *::before、*::after 是因为伪元素不写进去不会被匹配到。
注意:全局切到 border-box 后,老代码里那些「靠 width 加上 padding 撑开」的元素会突然变窄,行内元素之间的间距也可能整体位移。给老项目加这段重置前,先在一个页面试一下,别直接全站上线。
注意:
<input>、<textarea>、<button>在部分浏览器的默认样式里本来就是 border-box,全局重置对它们是「保持一致」,不会出问题;但如果你给输入框写width: 100%加padding,在 content-box 下会撑破父容器,这是表单页面最常见的溢出原因。
注意:页面顶部缺少
<!DOCTYPE html>时会进入怪异模式(quirks mode),此时默认盒模型就变成了 border-box。补上 DOCTYPE 后默认值变回 content-box,原有布局可能整体错位。遇到老页面「加上 DOCTYPE 就乱」,先怀疑这里。
小结
- 区别只有一条:
content-box的 width 只算内容区,border-box的 width 含 padding 和 border。 margin在两种模型里都不算进 width,别和 border 搞混。- 默认值是
content-box,要改就写box-sizing: border-box,属性不继承。 - 全局重置要写
*, *::before, *::after三个选择器。 - 调布局时用 Chrome「元素 → 样式」面板底部的盒模型图核对数字。
- 给老项目改盒模型前先小范围试,重点查表单和百分比宽度的地方。
转载请注明出处,版权归原作者所有。