下拉菜单被遮挡的根本原因是父容器创建了新层叠上下文,而非z-index设低;常见触发属性包括transform、filter、opacity

下拉菜单被遮挡是因为父容器创建了新层叠上下文
不是 z-index 设低了,而是它根本没机会生效。只要父级元素有 transform、filter、opacity 或 <code>will-change,就会触发新的层叠上下文(stacking context),子元素的 z-index 只在该容器内部比大小——哪怕你设成 9999,也盖不过同级模态框的 1050。
常见触发点:
-
.navbar用了backdrop-filter做毛玻璃效果 -
.card加了transform: translateY()微调位置 -
.navbar-collapse动画时自带transform - 自定义封装的
<div class="dropdown"> 外层加了 <code>filter: drop-shadow()验证方法:用 DevTools 选中遮挡它的元素 → 查
Computed标签页 → 看是否有transform、opacity、filter等属性被计算出来。.dropdown-menu 的 z-index 覆盖必须带上下文选择器
直接写
.dropdown-menu { z-index: 1060; }很可能无效,因为 Bootstrap 的默认样式权重更高,或你的 CSS 加载顺序靠前被覆盖了。正确做法是用更具体的选择器,且确保它作用在正确的上下文中:
- 在导航栏里被压?用
.navbar .dropdown-menu { z-index: 1060; } - 在模态框里失效?用
.modal .dropdown-menu { z-index: 1070; } - 嵌套在卡片里?用
.card .dropdown-menu { z-index: 1010; }
注意:这些选择器必须出现在 Bootstrap CSS 之后;如果用的是 CDN 编译版,别指望
$zindex-dropdown变量能生效——它只在 Sass 源码编译时起作用。移动端下拉错位 + 遮挡,根源常在 DOM 结构断裂
小屏下
.navbar-collapse.show展开后,如果.dropdown被包在自定义<div> 里(比如为了加 margin 或 flex 包装),就破坏了 Bootstrap 的 flex 上下文,导致 <code>z-index和定位同时失灵。必须保证:
- 所有下拉相关元素(包括右对齐的
.dropdown)都是<div class="collapse navbar-collapse"> 的**直接子元素** <li>不要在 <code>.nav-item外再套一层<div> 或 <code><span></span> -
.dropdown自身要有position: relative(Bootstrap 默认有,但自定义组件容易漏)
否则即使
z-index正确,菜单也会飘到页面左上角或被截断。三级菜单堆叠时 z-index 必须严格递增
Bootstrap 5 默认不支持三级菜单,手动实现时容易忽略层级递进规则:一级
z-index: 1000,二级就得1001,三级至少1002——不是“越大越好”,而是要形成明确的视觉栈。更关键的是:如果二级菜单的父容器(比如某个
.dropdown-menu)本身已处于一个被transform触发的层叠上下文中,那三级菜单的z-index再高也没用,必须把它的z-index提升到跟二级父容器同级甚至更高。实际调试中,最易被跳过的点是:没检查二级菜单的父级是否意外创建了新层叠上下文,只盯着
.dropdown-menu本身调数值。 - 在导航栏里被压?用


















