最可靠的解法是直接禁用 bootstrap 的 padding-right 补偿逻辑,如使用 data-bs-backdrop="static" 跳过整个滚动条补偿流程;或为 fixed 元素添加 .is-fixed 类由 bootstrap 统一管理;或用 scrollbar-gutter 替代并配合清空 js 补偿。

直接禁用 Bootstrap 的 padding-right 补偿逻辑最可靠,而不是试图覆盖或修它。
为什么加 data-bs-backdrop="static" 就不抖了
这个属性会让 Bootstrap 跳过整个滚动条补偿流程:不加 modal-open 类、不计算滚动条宽度、不往 body 上写内联 padding-right、也不设 overflow: hidden —— 它只禁用点击遮罩关闭,保留 ESC 键关闭能力。
-
data-bs-backdrop="static"是唯一不影响其他组件(如下拉菜单、Tooltip)的轻量解法 - 它不干扰
body的原始宽度,避免了 fixed 元素错位、第三方滚动库冲突、macOS Safari 返回 0 宽度等问题 - 只需在 modal 标签里加这一行:
<div class="modal" data-bs-backdrop="static"> <li>如果后续需要点背景关闭,删掉这个属性即可,无残留副作用</li> <h3>fixed 元素还在跳?加 <code>.is-fixed类Bootstrap 5 内置了对
position: fixed元素的补偿支持,但前提是显式加.is-fixed类 —— 它本身没样式,只是个 JS 钩子,用于监听modal-open状态并同步增减padding-right。- 给所有 fixed 元素加上该类:
<nav class="navbar fixed-top is-fixed"></nav>、<div class="hero-bg is-fixed"> <li>不加这个类,就得自己监听 <code>show.bs.modal/hidden.bs.modal手动同步padding-right,容易漏事件或重复执行 - 尤其在多层 modal 场景下,手动同步极易失效;而
.is-fixed由 Bootstrap 原生 JS 统一管理,更稳 - 先在 CSS 中设置:
body { scrollbar-gutter: stable both; } - 再强制清掉 Bootstrap 注入的 padding:
body.modal-open { padding-right: 0 !important; } - 最后在 JS 初始化前覆盖默认行为:
Bootstrap.Modal.Default.scrollbarWidth = 0; - 注意 fallback:iOS Safari 17.4 之前、旧版 Edge 等不支持
scrollbar-gutter,需检测CSS.supports('scrollbar-gutter', 'stable')并回退到动态测宽
想用
scrollbar-gutter替代padding-rightscrollbar-gutter: stable both是浏览器原生滚动条占位方案,它让滚动条空间始终预留,不依赖 JS 计算,对 fixed 元素天然友好 —— 但它不能单独生效,必须配合禁用 Bootstrap 的 JS 补偿逻辑。真正难的不是选哪个方案,而是排查有没有第三方库(比如
perfect-scrollbar或全局重置 CSS)悄悄改了body的overflow或内联padding-right—— 这些隐性覆盖往往比技术方案本身更耗时间定位。 - 给所有 fixed 元素加上该类:











