根本原因是width:100%仅作用于内容区,padding和border会额外叠加;需全局设置box-sizing:border-box并覆盖伪元素,且flex/grid子项须加min-width:0,替换元素还需max-width:100%或min-width:0等配合。

根本原因不是你写错了,而是 width: 100% 在默认盒模型下只管内容区,padding 和 border 会额外叠加——哪怕父容器宽 400px,子元素设了 width: 100%、padding: 16px、border: 1px,实际占宽就是 434px。
box-sizing: border-box 必须全局生效,否则等于没设
只写 * { box-sizing: border-box; } 不够,*::before 和 *::after 仍按 content-box 计算,伪元素一插进来就可能悄悄撑破布局。必须显式覆盖:
* { box-sizing: border-box; }*::before, *::after { box-sizing: border-box; }
检查是否生效,不能只看代码里写了什么,得打开开发者工具切到「Computed」面板,确认最终值是 border-box。框架(如 Tailwind)、重置样式、甚至浏览器默认表单样式都可能把它覆盖掉。
flex/grid 容器里的子元素光有 border-box 还不够
哪怕 box-sizing 正确,img、input、button 这类元素在 flex 或 grid 中默认带 min-width: auto,会拒绝收缩。结果就是 padding 一加,照样溢出。
立即学习“前端免费学习笔记(深入)”;
- flex 子项必须加
min-width: 0 - grid 子项(尤其用
1fr的)也得加min-width: 0 - 如果父容器本身没明确宽度(比如
display: flex但没设width或max-width),width: 100%就失去参照系
图片、iframe、表单控件这些“不听话”的元素要单独处理
box-sizing: border-box 解决的是尺寸计算逻辑,不是内容行为。替换元素和表单控件有自己的一套默认规则:
-
img、svg、iframe:必须加max-width: 100%+height: auto,否则原始尺寸照常溢出 -
input、textarea、button:除了box-sizing: border-box,还得加min-width: 0才能随容器缩 - 含
white-space: nowrap的文本:再准的盒模型也拦不住它不换行,得配overflow: hidden或text-overflow: ellipsis
最常被忽略的点是:当你看到元素宽度“刚好”等于父容器,却仍有横向滚动条,大概率是某个子元素(比如未重置的 img、漏掉的伪元素、或没设 min-width: 0 的 input)在暗处撑开了边界——box-sizing 只改计算方式,不改内容本身会不会溢出。


















