*, *::before, *::after 必须三者组合设置 box-sizing: border-box 才稳妥,因伪元素不继承 box-sizing、默认按 content-box 计算尺寸,漏写会导致装饰性布局错位;表单控件需单独覆盖,SVG 和替换元素需谨慎避免语义冲突。

直接写 *、*::before、*::after 三者组合并设 box-sizing: border-box,是最稳妥的全局设置方式。只写 * 会漏掉伪元素,导致布局意外撑开。
为什么必须显式包含 *::before 和 *::after
伪元素不继承父元素的 box-sizing,它们始终按浏览器默认的 content-box 计算尺寸。比如用 ::after 绘制一个三角形箭头,如果没重置,它的 width 和 height 会额外加上 padding 和 border,实际尺寸比预期大,常引发换行或溢出。
-
*选择器匹配所有真实 DOM 元素,但对伪元素无效 -
*::before和*::after是独立选择器,必须单独声明才能生效 - 漏掉任一者,都可能在装饰性布局(如卡片角标、下划线动画)中暴露问题
表单控件要单独处理,尤其旧版 Safari
input、textarea、select、button 在 Safari ≤12 或某些 Android WebView 中,原生 UI 层对 border-box 支持不完整:边框渲染错位、光标偏移、高度塌陷都可能发生。
- 不要依赖通配符“一劳永逸”,应显式覆盖:
input, textarea, select, button { box-sizing: border-box; } - 这条规则放在通配符之后,确保优先级足够,避免被第三方库样式覆盖
- 如果项目需兼容极旧环境,可加
!important,但更推荐用 scoped wrapper 隔离
哪些地方不能无脑套用 border-box
全局设置后,SVG 图形元素(如 <rect>、<circle>)和部分替换元素(如 <img>)虽不受影响,但一旦显式设了 display: block 并加 padding,border-box 就会生效——而它们的宽高语义本是坐标系尺寸,不是布局盒子。
立即学习“前端免费学习笔记(深入)”;
- SVG 内部图形建议保持默认
content-box,避免用通配符污染 -
<img>和<video>设了display: block后再加padding,会改变其容器行为,需人工验证视觉一致性 - JS 中读取
offsetWidth或getBoundingClientRect()的逻辑必须重新校验——值会变小,因为现在含padding和border
真正容易被忽略的是:全局规则生效后,所有基于尺寸计算的 JS 行为(比如 Tooltip 定位、Canvas 坐标映射、拖拽缩放边界判断)都会悄悄偏移。别只看样式是否正常,一定要在 DevTools 里对比切换前后的 offsetWidth 值变化。


















