先检查.modal是否被标记为“Stacking context”,若是则说明其与遮挡元素不在同一层叠上下文中,调z-index无效;再确认.modal是否直接挂载在body下,否则父容器创建新层叠上下文会使z-index仅局部生效。

模态框被遮住,先看 computed z-index 和 stacking context
打开 Chrome DevTools → Elements 面板,选中 .modal 元素,在右侧 Styles 标签页拉到底部 «Layout» 区域,检查是否被标记为 “Stacking context”。如果标了,说明它和遮挡它的元素(比如 .tippy-box、.flatpickr-calendar 或 .ck-toolbar-container)不在同一层叠上下文中——此时改 z-index 数值基本无效。
常见触发 stacking context 的属性包括:position: relative 且带 z-index(哪怕只是 0)、transform、opacity: 0.99、filter、will-change。这些往往藏在父容器上,比如 Vue 的 #app、React 的 div.root,或某个 .card 容器里。
模态框没挂到 body 下是最常见的真凶
Bootstrap 要求 .modal 必须是 document.body 的直系子节点,否则父级一旦创建新 stacking context,.modal 的 z-index: 1050 就只在局部生效,而 .modal-backdrop(z-index: 1040)在 body 层级,自然把它“盖住”。
- React:用
createPortal渲染到document.body,别直接 return<modal></modal> - Vue 3:用
<teleport to="body"><modal></modal></teleport>,不要依赖v-model挂在局部节点 - 原生 JS:在
modal.show()前执行document.body.appendChild(modalEl) - 检查 DOM 结构:开发者工具里确认
.modal的父节点是不是body,而不是某个div.container或div#app
改 z-index 不能硬堆 9999,得对齐 Bootstrap 变量体系
Bootstrap 5.3 的默认层级是语义化设计的:$zindex-dropdown: 1000、$zindex-fixed: 1030、$zindex-modal: 1050、$zindex-toast: 1080。硬写 z-index: 9999 !important 会破坏整个体系,比如让下拉菜单盖住模态框的 backdrop。
立即学习“前端免费学习笔记(深入)”;
安全做法:
- 用更具体的选择器覆盖,例如:
.navbar .dropdown-menu { z-index: 1060; } - 确保该 CSS 在 Bootstrap CSS 之后加载(检查
<link>顺序) - 同步给父容器加
position: relative,否则z-index不触发 - 第三方插件(如 Tippy.js)优先重定义其变量:
$tippy-z-index: #{$zindex-modal + 10},或用权重提升:.modal .tippy-box { z-index: calc(#{$zindex-modal} + 5) !important; }
父容器 overflow: hidden 会让 popover/tooltip 被裁剪
这不是 z-index 问题,而是视觉裁剪。当 .modal-body、.card-body 或自定义容器设置了 overflow: hidden、auto 或 scroll,所有 position: absolute 子元素(如 Popover、CKEditor 工具栏)都会被严格限制在边界内,再高的 z-index 也出不去。
修复方式:
- 移除直接包裹 Popover 的父容器上的
overflow(推荐) - 若需滚动,把
overflow移到更内层容器,比如<div class="scrollable-content"> <li>使用官方插件时,传 <code>container: 'body'选项,让 Popover 插入body下 - 确保定位基准正确:给父容器加
position: relative,避免 Popover 相对于错位祖先定位
真实项目里,90% 的“遮挡”不是数值不够大,而是 stacking context 错位或 DOM 挂载点不一致。动手前先看 Layout 面板有没有 “Stacking context”,再确认
.modal 是不是真的在 body 下——这两步跳过,后面所有 z-index 调整都是白忙。


















