→ 不生效。
正确结构示例:
<div class="modal fade" id="myModal">
<div class="modal-dialog modal-dialog-centered"> <!-- ✅ 只有这里加 -->
<div class="modal-content">
<div class="modal-header"></div>
<div class="modal-body"></div>
</div>
</div>
</div>
modal-dialog-centered 依赖父容器的 flex 布局
modal-dialog-centered 内部用的是 top: 50% + transform: translate(-50%, -50%),它能生效的前提是 .modal 元素已启用 flex 布局并设置了 align-items: center。Bootstrap 5 默认已内置这些样式,但以下情况会破坏它:
- 手动覆盖了
.modal 的 display 或 align-items
- 给
.modal 加了 overflow: hidden(可能切掉上半部分)
- 在
.modal.fade .modal-dialog 上重写了 margin-top(会和 fade 动画冲突)
如果发现加了类仍不居中,用浏览器 DevTools 检查 .modal 的 computed display 是否为 flex,align-items 是否为 center。
内容过高时自动上移,不是 bug 是预期行为
当模态框内容高度超过视口时,modal-dialog-centered 不会强制截断或滚动,而是让整个 .modal-dialog 向上偏移,确保顶部不超出屏幕。这是它的默认策略。
若需要内容可滚动且保持居中视觉,得额外加 modal-dialog-scrollable 类:
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<p>注意:<code>modal-dialog-scrollable</code> 和 <code>modal-dialog-centered</code> 可共存,但后者仍负责初始定位逻辑;滚动后,顶部锚点会变化,此时居中仅体现在首次弹出瞬间。</p>
<h3>移动端 Safari 需要 resize 监听?其实不用</h3>
<p>早期资料提到 iOS Safari 在横竖屏切换后需手动重置 <code>transform</code>,但现代版本(iOS 15+)已修复该问题。<code>modal-dialog-centered</code> 基于 <code>top: 50%</code> + <code>transform</code>,本身适配视口变化,无需 JS 监听 <code>resize</code> 或 <code>show.bs.modal</code> 事件。</p>
<p>唯一需要 JS 干预的场景是:模态框为动态创建(比如用 <code>document.createElement</code>),且在挂载 DOM 前就调用了 <code>show()</code> —— 此时元素无尺寸,<code>transform</code> 计算失败。解决办法很简单:</p>
<ul>
<li>先 <code>appendChild</code> 到 body</li>
<li>再调用 <code>new bootstrap.Modal(...).show()</code>
</li>
</ul>
<p>这个顺序错不了,但容易被忽略。</p>
</div>