对话框

dialog 元素是一种在 HTML 中表示任何类型的对话框的实用元素,了解其运作方式。

模态对话框是网页上一种特殊类型的弹出式窗口:这种弹出式窗口会中断用户,使其将注意力集中在该窗口上。弹出对话框有一些有效的用例,但在弹出对话框之前,应仔细考虑。模态对话框会强制用户专注于特定内容,并且至少暂时忽略页面的其余部分。

对话框可以是模态对话框(只能与对话框中的内容互动)或非模态对话框(仍可与对话框外的内容互动)。模态对话框会显示在其余页面内容之上。页面的其余部分处于不活跃状态,默认情况下会被半透明的背景遮盖。

用于创建对话框的语义 HTML <dialog> 元素具有语义、键盘互动,以及 HTMLDialogElement 接口的所有属性和方法。

下面是一个模态 <dialog> 的示例。使用“打开模态对话框”按钮打开对话框。对话框打开后,您可以通过以下三种方式关闭该对话框:使用“Esc”键、使用设置了 formmethod="dialog" 的按钮提交表单(或表单本身设置了 method="dialog"),以及使用 HTMLDialogElement.close() 方法。

HTMLDialogElement 有三个主要方法,以及从 HTMLElement 继承的所有方法。

dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */

由于此 <dialog> 是通过 HTMLDialogElement.showModal() 方法打开的,因此它是一个模态对话框。打开模态对话框后,除对话框本身外,所有其他内容都会失效并被遮盖。如果您将鼠标悬停在对话框外的界面上,就会发现所有元素的行为都像是设置了 pointer-events: none;;即使用于打开对话框的按钮也不会对互动做出响应。

对话框打开后,焦点会移至对话框中。系统会将焦点设置在该对话框中按顺序键盘导航顺序的第一个元素上。如果您反复按 tab 键,您会发现,只有在模态对话框打开时,对话框中的内容才能获得焦点。只要模态对话框处于打开状态,模态对话框之外的所有内容都处于不活跃状态。

关闭对话框(无论是否为模态对话框)后,焦点会返回到打开对话框的元素。如果您以编程方式打开的对话框并非基于用户操作,请重新考虑。如果必须,请确保将焦点放回对话框打开前的焦点位置,尤其是在用户在不与对话框互动的情况下关闭对话框时。

有一个全局 inert 属性,可用于停用某个元素及其所有后代(除了任何处于活动状态的对话框)。使用 showModal() 打开模态对话框时,无需额外设置即可实现惰性或停用;系统不会明确设置该属性。

您可以使用 ::backdrop 伪元素为遮盖除对话框以外的所有内容的背景设置样式。只有在使用 .showModal() 方法显示 <dialog> 时,背景才会显示。此伪元素与所有背景匹配,包括使用 Fullscreen API 时显示的背景,例如在全屏模式下观看与屏幕或显示器宽高比不一致的视频时。

非模态对话框

HTMLDialogElement.show() 同样会打开一个对话框,但不会添加背景或导致任何内容变为不活跃状态。 Esc 键不会关闭非模态对话框。因此,确保添加关闭非模态对话框的方法更为重要。这样一来,如果关闭器位于对话框之外,焦点将移至打开对话框的元素,这可能不是最佳的用户体验。

虽然规范并未正式要求提供用于关闭对话框的按钮,但请将其视为必需的功能。Esc 键会关闭模态对话框,但不会关闭非模态对话框。可接收焦点的可见按钮可改善无障碍功能和用户体验。

关闭对话框

您无需使用 HTMLDialogElement.close() 方法即可关闭对话框。您根本无需 JavaScript。如需在不使用 JavaScript 的情况下关闭 <dialog>,请通过在 <form> 上设置 method="dialog" 或在按钮上设置 formmethod="dialog",在表单中添加对话框方法。

当用户通过 dialog 方法提交数据时,系统会保留用户输入数据的状态。虽然会发生提交事件(表单会经过约束条件验证,除非设置了 novalidate),但系统不会清除或提交用户数据。不使用 JavaScript 的关闭按钮可以编写为:

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

您可能已经注意到,此示例中的关闭 <button> 设置了 autofocus 属性。在 <dialog> 中设置了 autofocus 属性的元素在网页加载时不会获得焦点(除非网页在加载时对话框处于可见状态)。不过,当对话框打开时,它们会获得焦点。

默认情况下,当对话框打开时,对话框中第一个可聚焦的元素将获得焦点,除非对话框中的其他元素设置了 autofocus 属性。为关闭按钮设置 autofocus 属性可确保在对话框打开时该按钮会获得焦点。不过,在 <dialog> 中添加 autofocus 时,应慎之又慎。系统会跳过序列中位于自动聚焦元素前面的所有元素。我们会在“聚焦”课程中进一步讨论此属性。

HTMLDialogElement 接口包含 returnValue 属性。使用 method="dialog" 提交表单会将 returnValue 设置为用于提交表单的提交按钮的 name(如果有)。如果我们写的是 <button type="submit" name="toasty">close</button>,则 returnValue 将为 toasty

打开对话框时,系统会显示布尔值 open 属性,表示对话框处于活动状态且可以与之互动。如果通过添加 open 属性(而不是通过 .show().showModal())打开对话框,则该对话框将是非模态对话框。HTMLDialogElement.open 属性会返回 truefalse,具体取决于对话框是否可供互动,而不是取决于对话框是否为模态对话框。

虽然 JavaScript 是打开对话框的首选方法,但在网页加载时添加 open 属性,然后使用 .close() 将其移除,有助于确保即使 JavaScript 不可用,对话框也能正常显示。

其他详情

请勿使用 tabindex

用于打开对话框的元素及其包含的关闭按钮(以及可能的其他内容)可以接收焦点并具有互动性。<dialog> 元素不可互动,也不会收到焦点。请勿将 tabindex 属性添加到对话框本身。

ARIA 角色

隐式角色为 dialog。如果对话框是确认窗口,用于传达需要用户确认或其他响应的重要消息,请设置 role="alertdialog"。该对话框还应具有可访问的名称。如果可见文本可以提供无障碍名称,请添加 aria-labelledby="idOfLabelingText"

CSS 默认值

请注意,浏览器会为 dialog 提供默认样式。Firefox、Chrome 和 Edge 在其用户代理样式表中设置 color: CanvasText; background-color: Canvas;,而 Safari 则设置 color: black; background-color: white;color 是从 dialog 继承的,而不是从 body:root 继承的,这可能出乎意料。background-color 属性不会被继承。

检查您的理解情况

测试您对对话框元素的了解程度。

如何设置对话框后面的区域的样式?

使用 ::background 伪元素。
请重试。
使用 ::backdrop 伪元素。
正确!
使用 background 属性。
请重试。