content-box下width仅指内容区宽度,实际占位宽=width+左右padding+左右border;border-box下width包含内容、padding和border,内容区宽=width−左右padding−左右border。

box-sizing: content-box 是怎么算宽度的
默认情况下,所有元素都走 box-sizing: content-box,也就是“标准盒模型”:你写的 width: 200px,就只是内容区宽 200px,不包含任何 padding 和 border。
实际占位宽度 = width + 左右 padding + 左右 border(margin 不影响自身尺寸,但影响它和邻居的距离)。
- 比如:
width: 200px; padding: 10px; border: 2px solid #000;→ 实际宽 = 200 + 10×2 + 2×2 = 224px - 两个并排的
width: 50%元素,只要加了哪怕 1px 的padding或border,就可能撑出父容器、被迫换行 - 用 JS 读
offsetWidth时,拿到的就是这个“含 padding + border”的总宽,不是你写的width
box-sizing: border-box 是怎么改计算逻辑的
box-sizing: border-box 把 width 的含义从“内容宽”变成“整个盒子(内容+padding+border)的总宽”,padding 和 border 不再往外撑,而是往里挤内容。
内容区宽 = width − 左右 padding − 左右 border;总占位宽 = width + 左右 margin。
立即学习“前端免费学习笔记(深入)”;
- 同样例子:
width: 200px; padding: 10px; border: 2px solid #000;→ 实际宽稳稳 200px,内容区只剩 200 − 20 − 4 = 176px - 响应式布局中写
width: 100%+padding: 16px,不用再手动减去 padding,直接生效 - 组件库(如 Ant Design、Element Plus)内部几乎全用
border-box,避免子元素因 padding/border 溢出
为什么全局设 *, *::before, *::after { box-sizing: border-box; }
这是现代 CSS 开发最基础的“防坑预设”,不是可选项,是必选项。
- 浏览器默认只对部分表单控件(如
input、textarea)用了border-box,其他全是content-box,不统一就容易错乱 -
*选择器权重低,不会覆盖你后面显式写的box-sizing: content-box(真有需要时仍可覆盖) - 注意:IE8+ 全支持
box-sizing,无需 polyfill;但旧版 Android Browser(4.3 及以下)有 bug,不过现在基本可忽略
什么时候非得用 content-box?
极少,但存在——主要出现在两类场景:
- 需要 JS 精确控制内容区域尺寸,且依赖
offsetWidth/getBoundingClientRect()返回“含边框+内边距”的原始值做计算(比如拖拽缩放、Canvas 坐标映射) - 对接遗留系统或第三方 UI 组件,它们内部按标准模型设计,强行切
border-box可能导致 padding 错位、图标被裁剪 - 别为了“语义清晰”而坚持用
content-box:CSS 的语义从来不在 width 是否含 padding,而在你是否让布局可预期
真正容易被忽略的点是:margin 永远不参与 box-sizing 计算,无论哪种模型,它都只管“盒子和邻居之间空多少”。很多人调 layout 时反复折腾 width 和 padding,最后发现是 margin 叠加导致溢出——先看 computed 样式里的 margin 值,比猜更可靠。










