:modal伪类仅对调用showModal()的原生<dialog>生效,严格绑定浏览器模态栈,同一时间仅栈顶一个匹配;不支持Shadow DOM;样式仅作用于元素自身,不影响::backdrop或子元素。

只对 showModal() 触发的原生 <dialog> 生效
伪类 :modal 不是“当前可见就匹配”,而是严格绑定浏览器模态栈机制。只有调用 dialog.showModal() 的原生 <dialog> 元素才会被推入模态栈顶层,此时 dialog:modal 才能选中它。用 .show()、open = true 或 CSS 控制显隐,都完全不触发 :modal。
同一时间仅最顶层一个 <dialog> 匹配 :modal
即使页面中有多个 <dialog>,且都调用了 showModal()(比如嵌套打开),:modal 也只匹配当前栈顶那个——后一次 showModal() 会覆盖前一次,但不会让两个同时生效。这不是 bug,是规范定义的行为。
别在 Shadow DOM 里用 :modal
目前所有主流浏览器(Chrome 105+、Firefox 103+、Safari 15.6+)均未明确定义 :modal 在 Shadow DOM 中的表现。实测中,有的浏览器完全忽略,有的只在 open shadow root 下部分生效,行为不可靠。若需封装模态逻辑,应确保 <dialog> 在 light DOM 中,或改用 class 控制状态。
:modal 样式只作用于元素自身,不涉及遮罩或兄弟节点
dialog:modal 设置的 background-color、border、transform 等,只渲染在 <dialog> 自身上。它不会影响 ::backdrop(得单独写 dialog::backdrop),也不会继承给子元素,更不会波及父容器或同级元素。想控制遮罩层样式,必须另起规则;想让子内容响应模态状态,得靠 JS 切换 class 或用 :has(:modal)(注意兼容性)。
立即学习“前端免费学习笔记(深入)”;
真正容易被忽略的是:一旦 :modal 没生效,90% 的原因是没调用 showModal(),而不是选择器写错或浏览器不支持。检查控制台里是否真执行了那行 JS,比反复调样式权重更有效。


















