必须给 .modal-body 设 max-height、overflow-y: auto 和 -webkit-overflow-scrolling: touch 才能滚动,因父级 flex 布局无高度限制导致滚动上下文被截断,且 ios safari 需该属性启用惯性滚动。

为什么 .modal-body 加了 overflow-y: auto 还不滚动
根本不是样式没生效,而是 .modal-body 没有可计算的高度边界——overflow-y: auto 在高度无限时永远不触发滚动。Bootstrap 的 .modal-dialog 默认是 display: flex,而 .modal-content 又没设高度限制,导致整个模态框随内容撑开,浏览器只能让 body 滚动。
- 别给
.modal-dialog或.modal-content加height或max-height,会破坏垂直居中和响应式缩放 -
.modal-body是唯一该设高度的区域,必须显式加max-height(别用height,小屏会被裁) - 常见错误:在
.modal-body里用了display: flex; flex-direction: column,但没给子容器设flex: 1,高度塌陷 - 嵌套了
position: absolute元素也会脱离文档流,干扰高度计算
移动端 Safari 滚不动或卡顿怎么办
iOS Safari 对 flex 容器内滚动支持弱,即使 .modal-body 高度超限、overflow-y: auto 已设,仍可能无惯性、滑不过界、松手即停。
- 必须加
-webkit-overflow-scrolling: touch,且只作用于真正滚动的元素——也就是.modal-body - 这个属性只对 WebKit 内核生效(Chrome/Safari/Edge),Firefox 不识别也不需要
- 如果用了第三方滚动库(如
overlay-scrollbars),它会接管原生滚动,这行就无效 - 较新 Safari 已标记为 deprecated,但目前仍是解决卡顿最可靠的方式
modal-dialog-scrollable 类为什么没效果
这个类只是“启用滚动逻辑”的开关,不是“开箱即用的滚动方案”。Bootstrap 5.2+ 中它默认给 .modal-body 设 max-height: 60vh 和 overflow-y: auto,但这个值在表单或富文本场景下常不够用,且极易被破坏。
- 父级
.modal-content或.modal-dialog被设了height: 100%或flex: 1,子元素无法继承有效高度 - 你在
.modal-body里用了display: flex却没给子容器设flex: 1,高度塌陷 - 推荐显式覆盖:
<div class="modal-body" style="max-height: 75vh; overflow-y: auto; -webkit-overflow-scrolling: touch;"> <li>别依赖默认值——60vh 在 iPhone SE 等小屏上可能刚展开就截断</li> <h3>滚动后点不到 backdrop 关闭模态框</h3> <p>这不是滚动本身的问题,而是 <code>z-index错乱的副作用。当.modal-body内某个元素(比如富文本编辑器、下拉菜单、自动聚焦的输入框)获得焦点,JS 可能临时提升它的z-index,盖住.modal-backdrop(默认z-index: 1040)。- 检查是否对
.modal-body或其子元素写了position: relative+z-index - 确保所有第三方组件初始化后没偷偷改
z-index,尤其注意vue-select、quill、flatpickr - 在
shown.bs.modal事件里兜底:$('#myModal').on('shown.bs.modal', () => { $('.modal-body *').css('z-index', 'auto'); }); - 别给
.modal-backdrop以外的元素设高于1050的z-index
flex或height设置,以及移动端 Safari 对-webkit-overflow-scrolling的强依赖——漏掉任意一环,滚动就失效。 - 检查是否对











