根本原因是width:100%仅作用于内容区,padding和border默认额外叠加;须全局设置 , ::before, *::after {box-sizing:border-box}并验证computed面板生效,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 不等于它真起效。唯一可信方式是打开开发者工具,切到「Computed」面板,查目标元素的 box-sizing 值:
- 如果显示
content-box(哪怕只有一条横线划掉你的规则),那width: 100%就一定不包含padding和border -
* { box-sizing: border-box; }不够,*::before和*::after仍按content-box渲染,必须显式覆盖:*::before, *::after { box-sizing: border-box; } - CSS-in-JS(如 styled-components)、Shadow DOM、UI 库(如 Ant Design)可能覆盖你的设置,得在对应 scope 内单独声明
flex/grid 容器里表单控件和图片必须加 min-width: 0
哪怕 box-sizing 正确,<input>、<img>、<button></button> 这类元素在 flex 或 grid 中默认有 min-width: auto,会拒绝收缩。结果就是 padding 一加,照样溢出:
- flex 子项必须加
min-width: 0 - grid 子项(尤其用
1fr的)也得加min-width: 0 - 更彻底写法:
flex: 0 1 auto(等价于flex-basis: auto+flex-shrink: 1),压制初始宽度
替换元素和 inline 元素要单独处理
box-sizing: border-box 解决的是尺寸计算逻辑,不是内容行为。替换元素和表单控件有自己的一套默认规则:
-
<img>、<iframe></iframe>、<svg></svg>:必须加max-width: 100%+height: auto,且设display: block(否则max-width参照行框而非父容器) -
<input>、<textarea></textarea>、<button></button>:除了box-sizing: border-box,还得加min-width: 0 - 含
white-space: nowrap的文本:再准的盒模型也拦不住它不换行,得配overflow: hidden或text-overflow: ellipsis
最常被忽略的点是:当你看到元素宽度“刚好”等于父容器,却仍有横向滚动条,大概率是某个子元素(比如未重置的 <img>、漏掉的伪元素、或没设 min-width: 0 的 <input>)在暗处撑开了边界——box-sizing 只改计算方式,不改内容本身会不会溢出。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











