Dropdown-menu 被遮挡的主因是父级创建了独立层叠上下文或祖先缺失定位,而非 z-index 数值不足;需检查 transform、opacity 等触发条件,并确保祖先元素有 position:relative 等定位属性。

Bootstrap 的 dropdown-menu 被遮挡,**不是 z-index 值不够大,而是它没落在正确的层叠上下文中**。盲目调高 z-index 很可能无效,甚至引发新冲突。
为什么改了 z-index 还是被盖住
常见真凶不是数值本身,而是父级意外创建了新层叠上下文:
-
transform、perspective、filter、opacity 、<code>will-change或isolation: isolate都会触发独立层叠上下文 - 一旦触发,子元素的
z-index就只在该容器内生效,和页面其他元素无关 - 比如
.navbar用了transform: translateY(0),里面的.dropdown-menu再设z-index: 9999也压不过外部的.modal
.dropdown-menu 在 .accordion 里被下一项盖住
根本原因是 .accordion-item 默认 position: static,不构成层叠容器,所有下拉菜单都挤在同一个根上下文里,后渲染的项自然覆盖前面的浮层。
- 必须给每个
.accordion-item加position: relative - 再用
:nth-child()或:first-child控制顺序,例如:.my-accordion .accordion-item { position: relative; } .my-accordion .accordion-item:first-child { z-index: 10; } .my-accordion .accordion-item:not(:first-child) { z-index: 1; } - 别只写
.dropdown-menu { z-index: 2000 }——没用,祖先没定位,z-index不生效
移动端点不开、点两次才展开
大概率是 .dropdown-backdrop 在作祟:它默认 position: fixed,在某些 WebView 里会盖住菜单,导致第一次点击穿透失败。
立即学习“前端免费学习笔记(深入)”;
- 加一行 CSS 即可:
.dropdown-backdrop { position: static !important; } - 不要用
display: none,否则关闭逻辑会中断 - 同时确认触发元素有且仅有
data-bs-toggle="dropdown",拼错或漏掉都会让 JS 实例初始化失败 - 动态插入的菜单(如 AJAX 加载)需手动初始化:
new bootstrap.Dropdown(element)
模态框、导航栏、手风琴混用时的层级协调
Bootstrap 5.3 的默认值是:$zindex-dropdown: 1000、$zindex-fixed: 1030、$zindex-modal: 1050、$zindex-toast: 1090。硬塞 9999 只会让后续加个 tooltip 或 popover 又得重调。
- 推荐统一收口到 CSS 自定义属性:
:root { --zindex-dropdown: 1000; --zindex-navbar: 1030; --zindex-modal: 1050; }然后各处用z-index: var(--zindex-modal) - 第三方组件(如
select2、flatpickr)的z-index也建议纳入同一套变量管理 - 如果必须 JS 控制挂载位置(比如防
transform截断),用boundary: 'window':new bootstrap.Dropdown(el, { boundary: 'window' });
真正难的从来不是调数字,而是判断当前元素属于哪个层叠上下文——打开开发者工具,看 computed 栏里的 position 和 z-index 是否生效,比瞎猜快十倍。


















