z-0到z-3类根本不是为覆盖组件设计的:它们仅对应z-index 0/100/200/300(或0–3),远低于.dropdown-menu(1000)、.modal(1055)等组件层级,专用于局部微调(如badge盖input边框),且必须配合position类(如position-relative)使用,否则无效。
z-0到z-3类根本不是为覆盖组件设计的
bootstrap 5 的 z-0 到 z-3 实用类只对应 z-index: 0、1、2、3(部分版本是 0/100/200/300,但量级一致),而 .dropdown-menu 默认是 1000,.modal 是 1055。你给一个按钮加 z-3,它照样被 .navbar(1030)压住——这不是 bug,是设计意图:这些类只用于局部微调,比如 badge 盖过 input 边框。
常见错误现象:<div class="z-3">菜单</div> 完全没效果,因为没配 position;或者加了 position-relative 还是被盖,那大概率是父容器创建了新层叠上下文。
- 必须同时使用定位类,例如
class="position-relative z-3" -
z-3是上限,不支持z-4或更高数字类名 - 别指望靠它盖过
.dropdown-menu、.modal、.toast等组件
想盖过 .dropdown-menu 或 .modal,得对齐语义变量
Bootstrap 的真实层级体系藏在 Sass 变量里:$zindex-dropdown: 1000、$zindex-modal: 1055、$zindex-toast: 1090。这些值之间留了空档,是刻意设计的可扩展空间。
如果你用 Sass 编译项目:
- 在引入 Bootstrap 前重定义变量,例如:
$zindex-dropdown: 1060; - 再让自定义下拉菜单的父容器设
z-index: 1061(比它高 1 即可) - 避免直接改 Bootstrap 源码或硬写
z-index: 9999,否则和后续组件冲突
如果只用 CDN CSS(无构建流程):
- Bootstrap 5.3+ 支持 CSS 自定义属性,在
:root中覆盖:--bs-zindex-dropdown: 1060; - 或用更具体选择器覆盖,例如:
.navbar .dropdown-menu { z-index: 1060; } - 务必确保该规则加载顺序在 Bootstrap CSS 之后
父容器悄悄创建了层叠上下文,z-index 就失效
这是最常被忽略的真凶。哪怕你写了 z-index: 9999,只要目标元素的某个父级满足以下任一条件,它的 z-index 就只在这个“小盒子”里有效:
- 父元素有
position: relative且z-index: 0(哪怕只是 0) - 父元素用了
transform、opacity: 0.99、filter、will-change - 父元素是
.accordion-item或.card(默认position: static,但多个同级项会互相覆盖)
验证方法:Chrome DevTools → Elements → 找到该元素 → 右侧 Styles 标签页下方 Layout 区域,看有没有 “Stacking context” 提示。
修复建议:
- 优先移除父级的
transform(改用top/left+position: relative) - 若无法移除,把下拉菜单挂到
body下:new bootstrap.Dropdown(element, { boundary: 'window' }); - 检查父容器是否已定位,没定位就补上
position: relative
移动端和 modal 内部下拉菜单特别容易踩坑
iOS Safari 对 position: fixed 和层叠上下文极其敏感,双指缩放或地址栏收起时,fixed 元素可能突然“掉层”,不是 z-index 数值问题,而是定位基准漂移。
modal 内部初始化下拉或编辑器(如 CKEditor)时,.modal 的 z-index: 1055 创建了强隔离上下文,子菜单默认没有 z-index,自然掉在下面。
- 手动给子菜单设
z-index: 1056(比 modal 高 1 即可) - 但前提是它没被更上层的上下文包裹,比如
.modal-content本身也要确认是否已定位且层级足够 - 某些 UI 库(如 CKEditor)需单独提升工具栏层级:
.ck-toolbar-container { z-index: 1060; } - 禁用 modal 的焦点劫持,避免干扰内部交互:
$('#myModal').off('focusin.bs.modal');
真正复杂的从来不是数值大小,而是层叠上下文是否被意外截断、父容器是否隐式封闭、以及不同设备对 fixed 定位的处理差异。这些地方一旦出问题,调再大的 z-index 都是白搭。











