根本原因是浏览器默认box-sizing: content-box,width仅指内容区,padding和border额外叠加;需全局设置, ::before, *::after { box-sizing: border-box }才有效,漏掉伪元素或table/td未显式声明会导致尺寸失控。

根本原因不是 width 写错了,而是浏览器默认按 box-sizing: content-box 计算尺寸——你写的 width: 300px 只管内容区,padding 和 border 全部额外叠加在它外面。
为什么 width: 100% 还会溢出
因为 width: 100% 是相对于父容器的 content 区宽度 计算的。如果父容器有 padding: 20px,那它的 content 区只有 300px - 40px = 260px;子元素设 width: 100% 就只占这 260px,再叠上自己的 padding: 12px 和 border: 1px,实际就变成 260px + 24px + 2px = 286px —— 看似没超,但若父容器本身宽 300px,它自己又没撑开高度或预留空间,视觉上就“顶到边”甚至滚动条意外出现。
常见现象包括:
-
max-width: 100%失效 - 横向滚动条在不该出现时弹出
- 开发者工具里「Computed」面板显示总宽远大于你写的
width
box-sizing: border-box 必须全局写对才生效
只给某个 .card 加 box-sizing: border-box 不够,它的子元素(比如 .card-header)若仍是 content-box,padding 还是会往外叠。真正起效的方式是统一重置:
立即学习“前端免费学习笔记(深入)”;
*, *::before, *::after {
box-sizing: border-box;
}漏掉 *::before 或 *::after 是真实高频翻车点——它们常被用于清除浮动、图标插入等,一旦仍按 content-box 计算,就会悄悄撑开布局。
注意:
-
html或body上设box-sizing没用,它不继承 - CSS-in-JS 库(如 styled-components)可能服务端渲染顺序错乱,导致首屏样式未注入,要把这条规则提至
<head>最顶部 -
table、td默认无视box-sizing,必须显式声明
flex 子项溢出时,box-sizing 单独不够
哪怕你给 input 或文本容器加了 box-sizing: border-box,只要它在 display: flex 容器里,且没设 min-width: 0,就大概率还会撑破父容器。
原因:flex 项目默认 min-width: auto,它会把内容固有宽度当底线,直接锁死 flex-shrink。解决必须两步走:
- 显式加
min-width: 0(水平布局)或min-height: 0(垂直布局) - 配合
overflow-wrap: break-word或text-overflow: ellipsis控制内容呈现
特别注意:text-overflow: ellipsis 需三件套:white-space: nowrap + overflow: hidden + 明确宽度(或由 flex 分配),缺一不可。
哪些元素天生“不听话”,box-sizing 压不住
box-sizing: border-box 解决的是尺寸计算逻辑问题,但对以下情况无直接作用:
-
<img>、<svg>、<iframe>:必须额外加max-width: 100%和height: auto -
<input>、<button>:内置min-width: auto,得配min-width: 0才能收缩 - 含
white-space: nowrap的文本:盒模型再准也没用,得靠overflow-wrap: break-word或text-overflow: ellipsis - 绝对定位元素:
box-sizing对margin完全无效,外边距仍在盒模型外部
最容易被忽略的一点:当你在调试工具里看到元素宽度“刚好”等于父容器,却仍有横向滚动条,大概率是某个子元素(比如伪元素、未重置的 img 或 flex 项)悄悄溢出了——box-sizing 只管尺寸定义方式,不管内容本身会不会撑开边界。


















