showModal() 打开的 dialog 始终在最顶层,因其被插入独立于 DOM 和 z-index 的 #top-layer 渲染层;show() 则遵循普通 CSS 层叠规则,易被父容器样式遮挡或裁剪。

showModal() 打开的 dialog 一定在最顶层,show() 的不保证
浏览器对 showModal() 有硬性规范:它会把 dialog 插入到一个叫 #top-layer 的特殊渲染层,这个层独立于普通 DOM 树和 z-index 层级体系,天然高于所有 position: fixed 或 z-index: 9999 元素。而 show() 只是让 dialog 变成 display: block,它依然遵循普通 CSS 层叠规则——父容器的 transform、overflow: hidden、甚至 z-index 都可能把它“压住”或裁剪。
多个 showModal() 调用时的层级顺序由调用先后决定
连续调用两次 showModal(),后打开的 dialog 会盖在前一个上面,这是浏览器原生行为,不需要手动管理 z-index。但注意:show() 没这待遇——两个 show() 出来的 dialog 之间如果没设 z-index,就按 DOM 顺序或默认层叠上下文排,很容易被遮挡。
- 真实层级只取决于
showModal()的调用顺序,不是 DOM 位置 -
getComputedStyle(dialog).zIndex对showModal()结果始终返回空字符串,别靠它判断 - 若需精确控制多个模态框叠加顺序(比如 toast + confirm),必须自己维护栈,例如用数组
dialogStack记录当前打开的showModal()实例
backdrop 的层级问题只影响 showModal()
::backdrop 是 showModal() 自动创建的伪元素,它和 dialog 本体同属 #top-layer,但它的绘制顺序固定在 dialog 内容之下、页面内容之上。而 show() 根本不生成 ::backdrop,所以不存在 backdrop 被裁剪或层级错乱的问题——但它本来就不该有遮罩。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
dialog::backdrop { background: rgba(0,0,0,0.5); }必须显式写,否则 Chrome/Safari 显示为空白 - 如果 dialog 父容器有
transform或overflow: hidden,::backdrop会被裁剪——这是showModal()独有的视觉 bug,show()不涉及 backdrop,也就没这问题 - Firefox 目前只做逻辑阻塞(禁焦点、拦 Tab),不渲染
::backdrop,所以即使写了样式也看不到
实际开发中容易忽略的关键点
你很少需要手动干预层级,但一旦遇到 dialog 被遮住、backdrop 显示不全、或 Safari 里弹窗偏移,问题几乎都出在 DOM 挂载位置或父容器样式上——而不是 z-index 数值本身。尤其要注意:dialog 元素必须已挂载到 document.body(或至少 document 根节点下)才能正确进入 #top-layer;如果它还卡在某个 div 里,showModal() 仍会失败或表现异常。
立即学习“前端免费学习笔记(深入)”;


















