z-index不生效的根本原因是元素未定位或被父级层叠上下文限制;必须满足position非static且未被低层级层叠上下文包裹,再检查opacity、transform等触发新层叠上下文的属性。
z-index 不生效?先看定位和层叠上下文
绝大多数时候,z-index 看似写了却没用,根本不是数值太小,而是它压根没生效。两个硬条件缺一不可:元素必须有 position 且不为 static;它不能被父级“关进”一个低层级的层叠上下文里。
常见错误现象:给弹窗按钮加了 z-index: 9999,结果还是被导航栏盖住;下拉菜单展开后一部分被截断;CKEditor 工具栏在 Modal 里显示不全。
- 检查目标元素是否设置了
position: relative、absolute、fixed或sticky——static下z-index完全被忽略 - 用 Chrome DevTools 的 «Layers» 面板或 Elements → Styles 右侧的 «Layout» 标签页,确认该元素是否被标记为 “Stacking context”
- 重点排查父级是否无意触发了新层叠上下文:比如
opacity: 0.99、transform: translateZ(0)、filter: blur(1px),哪怕只是加了个will-change
Bootstrap Modal 和编辑器/浮层冲突怎么调
Bootstrap 默认 Modal 的 z-index 是 1050,而 CKEditor 工具栏默认是 1000,Dropdown 面板是 1030——数值差一点,就直接被盖住。这不是 Bug,是设计预期,但你需要主动对齐。
使用场景:在 modal-body 里初始化 ClassicEditor,气球工具栏(balloon toolbar)或下拉菜单(如字体选择)被 Modal 裁剪。
- 在项目 CSS 中显式提升编辑器相关层级:
.ck.ck-toolbar-container { z-index: 1060 !important; }.ck-dropdown__panel { z-index: 1070 !important; } - 别只调子元素——如果父容器(比如
.modal-content)本身有z-index: 1050且已定位,那子元素再高也出不去;此时需同步确保它的z-index足够支撑 - 禁用 Bootstrap 的焦点劫持(避免干扰编辑器内部 focus 流程):
$('#myModal').on('shown.bs.modal', function() { $(this).off('focusin.bs.modal'); });
移动端 fixed 浮层被遮挡?iOS Safari 特别难搞
iOS Safari 对 position: fixed 的处理很敏感,尤其在地址栏收起/展开、双指缩放时,fixed 元素可能突然“掉层”,不是 z-index 问题,而是定位基准漂移了。
常见错误现象:Modal 在 iOS 上部分被系统导航栏或键盘挡住;自定义 toast 提示一闪而过或位置错乱。
- 避免给
fixed浮层的父容器加transform、perspective或opacity < 1,这些会强制 Safari 把 fixed 当作 absolute 处理 - Viewport 设置要克制:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">能缓解但非万能 - 关键浮层(如全局提示、菜单)建议改用
position: absolute+ JS 动态计算top/left,监听resize和scroll更新位置
怎么管好 z-index 数值,不靠猜也不堆魔数
写 z-index: 999999 是掩盖结构问题,还容易和第三方库(比如某些 UI 框架 modal 默认用 z-index: 2147483647)打架。真正要解决的是分层意识,不是数字大小。
参数差异:Bootstrap 5 的 $zindex-modal 默认是 1055,$zindex-dropdown 是 1000,你自定义组件必须跟这套体系对齐,而不是另起炉灶。
- 按功能角色划分区间,留余量:
基础层:--z-base: 0;导航:--z-nav: 100;浮层:--z-overlay: 1000;Modal:--z-modal: 1055;调试面板:--z-debug: 2000 - 统一用 CSS 自定义属性:
:root { --z-modal: 1055; }.modal { z-index: var(--z-modal); } - 所有需要参与层叠控制的元素,必须显式设
position,不要全局加position: relative来“保险”——它会意外创建层叠上下文
最常被忽略的一点:z-index 生效与否,90% 取决于你有没有意识到「层叠上下文」的存在。它不是抽象概念,是浏览器实实在在渲染时的分组逻辑。DevTools 的 Layers 面板不是玩具,是唯一能看清真实层级的窗口。










