<p>100vw将滚动条宽度计入视口总宽,导致元素实际宽度超过可用内容区而触发横向滚动;应优先用100%或calc(100vw - 滚动条宽度)替代。</p>

100vw 会把滚动条宽度算进视口里
当页面内容高度超过视口,浏览器自动加了垂直滚动条,这个滚动条本身占空间(通常 12–17px),但 100vw 的计算逻辑是「整个浏览器窗口的宽度」,不是「去掉滚动条后的可用宽度」。所以 width: 100vw 的元素实际宽度 = 视口总宽 = 内容区宽 + 滚动条宽。一旦它被放在 body 或 html 下,就会向右多出那几像素,触发水平滚动条 —— 形成自循环:有垂直条 → 触发 100vw 溢出 → 出现水平条 → 水平条又进一步挤压可用空间。
overflow-x: hidden 在 body 上为什么有时还压不住
根本原因不是样式没生效,而是父级容器(比如 html)没被约束。常见失效链:
-
body { overflow-x: hidden }生效了,但html元素没设width或max-width,子元素仍可撑开它 - 某个子元素用了
white-space: nowrap且含长 URL 或无空格字符串,overflow-x: hidden对它无效,除非同时配text-overflow: ellipsis和width - flex 容器里的图片或
textarea默认min-width: auto,哪怕父容器写了overflow-x: hidden,它也会拒绝收缩、硬顶出去
textarea 和 input 的溢出行为为啥不一样
微信小程序和部分移动端 WebView 中,textarea 是原生组件,它的渲染不完全走标准 CSS 盒模型。即使你写了 box-sizing: border-box 和 width: 100%,它内部仍自带一套不可覆盖的 padding 和边框偏移。表现就是:左右边缘比 input 多出 2–4px,尤其在真机上明显。这不是 bug,是历史兼容策略。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 对
textarea单独加负 margin:margin-right: -4px(需配合box-sizing: border-box) - 更稳妥的做法是用
calc(100% - 8px)替代width: 100%,预留出它固有的内边距余量 - 避免给
textarea父容器设padding,改用margin推开间距,防止嵌套叠加
检查溢出源最有效的办法是 outline 调试法
别一上来就改 overflow,先快速定位哪个元素在撑宽:
- 在开发者工具控制台执行:
$$('*').forEach(el => el.style.outline = '1px solid red'),所有元素立刻标红边框 - 观察哪块红框明显超出视口右边界,就是罪魁祸首
- 重点盯三类:未设
max-width: 100%的img、用了vw的全屏模块、position: absolute且 left/right 值过大的指示器
真正难处理的从来不是单个属性,而是 100vw、滚动条宽度、原生组件内建 padding、以及 flex 默认 min-width 这几者在不同环境下的组合效应。每次遇到横向滚动,优先查 computed 样式里的实际 width 值,而不是只看代码写了什么。


















