标准 · ARIA

角色 窗口

dialog

将容器标记为模态或非模态对话框。建议使用原生 <dialog> 元素配合 showModal()——它可自动处理焦点限制、顶层渲染、背景遮罩以及 Escape 关闭功能。仅在无法使用原生元素时才借助 role="dialog"。

适用场景

使用通过 .showModal() 打开的 <dialog> 元素。该原生元素在所有主流浏览器中均受支持,可自动处理背景失活、焦点限制、Escape 关闭、::backdrop 样式钩子以及顶层渲染,省去约 200 行脆弱的 JavaScript 代码。

仅在以下情况下才在 <div> 上使用 role="dialog"

  • 需要支持 Chrome 37 / Firefox 98 / Safari 15.4 之前的旧版浏览器(2026 年几乎不会出现此情况)。
  • 设计要求对话框不能位于顶层(极为罕见)。
  • 在重构过程中修补不可访问的自定义模态组件。

每个对话框都必须具有可访问名称(将 aria-labelledby 指向可见标题是最佳做法)。模态对话框还需要设置 aria-modal="true"

键盘与焦点契约

依据 APG 对话框(模态)模式

  • 打开时,焦点移至对话框内的第一个可聚焦元素(通常是关闭按钮或主要输入框)。
  • Tab 和 Shift+Tab 在对话框内部循环移动焦点——即”焦点限制”。从最后一个元素按 Tab 返回第一个;从第一个元素按 Shift+Tab 返回最后一个。
  • 按 Escape 关闭对话框。
  • 关闭后,焦点返回至触发对话框的元素。保存并恢复焦点是不可或缺的;失去位置的用户将无从定位。
  • 对话框打开期间,其余页面内容须设为 inert(或作为备用方案设置 aria-hidden="true" 且不可聚焦)。

常见错误

  • 自定义对话框缺少焦点限制。按 Tab 后焦点跳出对话框,用户丢失上下文。
  • 关闭时未将焦点还原至触发元素。下一次按 Tab 落在文档主体上。
  • 尽管背景内容在视觉上被对话框遮挡,仍可通过 Tab 键聚焦到背景元素。
  • 缺少可访问名称。对话框打开后,屏幕阅读器仅播报”对话框”。
  • 自定义对话框未设置 aria-modal="true"——辅助技术将其视为内联内容。
  • Escape 关闭对话框时,若对话框通过 portal 渲染,关闭动画期间键盘焦点可能丢失。

示例

<!-- 推荐用法 -->
<dialog id="confirm">
  <h2>Delete this draft?</h2>
  <p>This cannot be undone.</p>
  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="delete" autofocus>Delete</button>
  </form>
</dialog>
<script>
  document.getElementById('confirm').showModal();
</script>

<!-- 当无法使用 <dialog> 时 -->
<div role="dialog" aria-modal="true" aria-labelledby="dlgTitle">
  <h2 id="dlgTitle">Edit profile</h2>

</div>