一个元素的“最终宽度”是由多个属性共同作用的结果,而一切都始于 box-sizing 属性,它决定了元素的宽度和高度如何计算。
box-sizing 的值
box-sizing 有两个主要值:
content-box(默认值)
- 宽度和高度只包括内容区域。
- 你设置的
width和height就是内容区(content)的尺寸。 - 内边距(padding)和边框(border)会额外加到元素的总宽度和总高度上。
公式
总宽度 = width + padding-left + padding-right + border-left + border-right总高度 = height + padding-top + padding-bottom + border-top + border-bottom
border-box
- 宽度和高度包括内容、内边距和边框。
- 你设置的
width和height已经包含了padding和border。 - 内容区的实际宽度/高度会自动收缩。
公式
总宽度 = width(你设置的)总高度 = height(你设置的)内容区宽度 = width - padding-left - padding-right - border-left - border-right内容区高度 = height - padding-top - padding-bottom - border-top - border-bottom
视觉化对比
假设我们有一个 div,设置了以下样式:
div {
width: 200px;
height: 100px;
padding: 20px;
border: 5px solid blue;
}当 box-sizing: content-box;(默认)时:
- 内容区宽:
200px - 内容区高:
100px - 总宽度:
200 (内容) + 20 (左padding) + 20 (右padding) + 5 (左边框) + 5 (右边框) = 250px - 总高度:
100 (内容) + 20 (上padding) + 20 (下padding) + 5 (上边框) + 5 (下边框) = 150px
当 box-sizing: border-box; 时:
- 总宽度:
200px(你设置的,包含了 padding 和 border) - 总高度:
100px(你设置的,包含了 padding 和 border) - 内容区宽:
200 - 20 - 20 - 5 - 5 = 150px - 内容区高:
100 - 20 - 20 - 5 - 5 = 50px
对比图:
box-sizing: content-box; | box-sizing: border-box; |
|---|---|
![]() | ![]() |
为什么不是计算的 250×150
- 浏览器缩放级别:如果浏览器缩放不是 100%,会导致像素值出现小数
- 设备像素比 (DPR):高分辨率显示器的设备像素比可能导致计算结果出现小数
- 字体大小影响:某些情况下浏览器的默认字体大小设置会影响布局计算
可以发现content-box属性会受一些非代码问题导致的样式问题,如果对样式有更高像素级的追求,可以优先选择更直观的模型border-box。
边界盒模型重置
边界盒模型重置一般是考虑上面实践中看到的受设备、字体大小等影响最终样式的问题,可以在在 CSS 开头使用通配符重置盒子模型。
*,
*::before,
*::after {
box-sizing: border-box;
}这样,所有元素(包括伪元素)都使用更直观的 border-box 模型。
特殊情况和注意事项(debug 思路)
margin 折叠
可阅读:CSS Margin 折叠
- 对于块级元素,在垂直方向上的相邻
margin会发生折叠(合并)。 - 例如,上面盒子的
margin-bottom: 30px和下面盒子的margin-top: 40px相遇,它们之间的实际距离是max(30px, 40px) = 40px,而不是70px。
box-sizing: inherit
- 让元素继承其父元素的
box-sizing值。
outline(轮廓)
- 类似于
border,但它不占用空间,绘制在元素边框之外,不影响元素尺寸和位置。常用于高亮或:focus状态。
小结
要精确控制一个元素的尺寸,需要综合考虑一个“属性链”:
box-sizing → width/height → padding → border → margin


