dialog 的 open 属性不触发 css transition,必须用 class 控制动画;::backdrop 需显式设置初始透明度和 transition;关闭时需监听 transitionend 再调用 close();需正确管理焦点以符合可访问性要求。

dialog 的 open 属性不触发 CSS transition
直接给 dialog 写 transition: opacity 0.3s 没用——因为 open 是布尔属性,切换时 DOM 状态跳变,没有中间帧。浏览器不会从 opacity: 0 渐变到 opacity: 1,而是瞬间显示或隐藏。
必须用 class 控制动画,open 只保留语义和可访问性支持。
- 初始样式设为
opacity: 0; transform: scale(0.95); pointer-events: none; - 添加
is-open类后设为opacity: 1; transform: scale(1); pointer-events: auto; - 打开时:先
dialog.classList.add('is-open'),再dialog.showModal() - 关闭时:先
dialog.classList.remove('is-open'),等transitionend后再调用dialog.close()
::backdrop 无法直接加 transition,但可以手动控制
dialog::backdrop 是伪元素,不参与常规 DOM 流,也不能直接监听事件,但它支持 transition,前提是初始状态明确。
常见错误是只写 dialog::backdrop { background: rgba(0,0,0,0.6); },没设初始透明度,导致“啪”一下出现。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 必须写:
dialog::backdrop { background: rgba(0,0,0,0); transition: background 0.25s ease; } - 配合 JS 在打开时设置
dialog.style.backdropFilter = 'blur(0)'或仅靠 class 触发 backdrop 样式变化 - Safari 15.4+、Chrome/Firefox 支持良好;旧 Safari 需降级 fallback(如忽略 backdrop 动画)
点击遮罩关闭 dialog 时,动画容易错位
如果监听 click 事件并立即调用 dialog.close(),动画会中断——因为 close() 立即移除 open 属性,class 还没来得及移除,视觉上弹窗“卡住”或闪退。
正确做法是把关闭逻辑和动画解耦:
- 监听
click,判断e.target === dialog(代表点在 backdrop 上) - 触发
dialog.classList.remove('is-open') - 监听
transitionend,确认动画结束后再执行dialog.close() - 同时监听
keydown捕获Escape,同样走这套流程,保持行为一致
focus 管理和 tab 键顺序常被忽略
即使动画流畅、遮罩渐变到位,若焦点没锁住,键盘用户按 Tab 仍能切到背景元素——这既是体验断层,也违反 WCAG。
showModal() 会自动聚焦第一个可聚焦子元素,但前提是:
-
dialog内至少有一个tabindex="0"或可聚焦元素(如button、input) - 不要用
display: none或visibility: hidden隐藏内容,它们会让元素不可聚焦 - 关闭后,记得手动
triggerBtn.focus()回到触发按钮,否则焦点丢失
open、class、focus、transitionend 四者节奏对齐——稍一错位,就变成“半开半关”或“焦点飞走”。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










