Modal关闭后页面抖动是因modal-open类或padding-right样式未清理干净;多层Modal时需检查.show实例数再移除类;padding-right残留、!important覆盖、第三方滚动库干扰、static backdrop下手动干预及fixed元素遗漏均会导致该问题。

关闭后页面还在抖动,说明 modal-open 类没被正确移除,或者它的样式残留(尤其是 padding-right)还在生效——这不是“动画没结束”,而是滚动锁定状态没清理干净。
为什么 modal-open 没被删掉
Bootstrap 默认在任意一个 Modal 触发 hidden.bs.modal 事件时就移除 modal-open,但多层 Modal 场景下,底层 Modal 关了,上层还开着,modal-open 却被误删了。
- 用
document.querySelectorAll('.modal.show').length替代document.body.classList.contains('modal-open')判断是否真该删类 - 别在关闭回调里直接写
$('body').removeClass('modal-open')—— jQuery 可能因 DOM 状态不同步漏操作 - 监听
hidden.bs.modal时,必须检查当前还有没有其他.modal.show实例,只有数量为 0 才执行清理
padding-right 值残留导致视觉错位
Bootstrap 会动态计算滚动条宽度并设为 padding-right,比如 17px。但如果 Modal 关闭时没还原这个值,或被 !important 规则锁死,body 就一直带着这个内边距,内容区持续偏左。
- 全局 CSS 里写了
body { padding-right: 0 !important; }?它会阻止 Bootstrap 自动还原 - 第三方滚动库(如
overlay-scrollbars)会让document.body.offsetWidth - document.documentElement.clientWidth返回 0,导致 Bootstrap 补偿逻辑失效,后续还原也无从谈起 - 手动加过
document.body.style.paddingRight = '17px'却没在hidden.bs.modal里清空?记得补上document.body.style.paddingRight = ''
用了 data-bs-backdrop="static" 却又手动干预滚动
这个属性本意是跳过整个补偿链路:不加 modal-open、不设 padding-right、不改 overflow。但如果你同时又写了 JS 去 toggle modal-open 或硬设 padding-right,等于自己造了一套冲突逻辑。
- 启用
data-bs-backdrop="static"后,就别再监听show.bs.modal去手动加类或样式 - 如果业务后来要求支持点击遮罩关闭,切回默认行为前,务必确认所有手写的滚动控制代码已删除,否则抖动会复现
-
data-bs-backdrop="static"不影响data-bs-keyboard="false"等配置,可安全叠加
最常被忽略的其实是 fixed 元素——哪怕只漏一个没加 .is-fixed,Modal 打开时它不动,其他内容右移,关掉后又弹回,反复几次人眼就能明显感知“抖”。


















