对话框元素是一个有用的元素,用于表示 HTML 中的任何类型的对话框,了解它是如何工作的。
模态对话框是一种特殊的网页弹出框:一种打断用户以使其专注于自身的弹出框。弹出对话框有一些有效的用例,但在这样做之前应仔细考虑。模态对话框会强制用户专注于特定内容,并(至少暂时)忽略页面的其余部分。
对话框可以是模态的(只能与对话框中的内容交互)或非模态的(仍然可以与对话框外部的内容交互)。模态对话框显示在页面其余内容之上。页面的其余部分是 惰性的,并且默认情况下,会被半透明的背景幕遮挡。
用于创建对话框的语义化 HTML <dialog>
元素带有语义、键盘交互以及 HTMLDialogElement
接口的所有属性和方法。
模态对话框
这是一个模态 <dialog>
的示例。使用“打开模态对话框”按钮打开对话框。打开后,有三种关闭对话框的方式:Escape 键、提交一个按钮设置了 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()
方法打开的,因此它是模态对话框。打开模态对话框会禁用并遮蔽除对话框本身之外的所有内容。如果您将鼠标悬停在对话框外部的 UI 上,您会注意到所有元素的行为都好像设置了 pointer-events: none;
一样;即使是打开对话框的按钮也不会对交互做出反应。
当对话框打开时,焦点会移入对话框。焦点设置在该对话框内顺序键盘导航顺序中的第一个元素上。如果您反复按 Tab 键,您会注意到在模态对话框打开时,只有对话框内的内容才能获得焦点。只要对话框打开,模态对话框之外的所有内容都是惰性的。
当对话框关闭时(无论是模态还是非模态),焦点都会返回到打开对话框的元素。如果您以编程方式打开对话框而不是基于用户操作,请重新考虑。如果必须这样做,请确保焦点放回到对话框打开之前的位置,特别是当用户在不与对话框交互的情况下关闭对话框时。
有一个全局 inert
属性,可用于禁用元素及其所有后代,但任何活动的对话框除外。当使用 showModal()
打开模态对话框时,惰性或停用是免费提供的;该属性未显式设置。
可以使用 ::backdrop
伪元素来设置遮蔽除对话框之外所有内容的背景幕的样式。背景幕仅在 <dialog>
使用 .showModal()
方法显示时显示。此伪元素匹配所有背景幕,包括在使用 FullScreen API 时显示的背景幕,例如在全屏模式下观看宽高比与屏幕或监视器不同的视频时。
非模态对话框
HTMLDialogElement.show()
类似地打开一个对话框,但不添加背景幕或导致任何内容变得惰性。Escape 键不会关闭非模态对话框。因此,更重要的是确保您包含关闭非模态对话框的方法。这样做时,如果关闭器在对话框外部,请意识到焦点将转到打开对话框的元素,这可能不是最佳的用户体验。
虽然规范未正式要求使用按钮来关闭对话框,但请将其视为必需。Escape 键将关闭模态对话框,但不会关闭非模态对话框。能够接收焦点的可见按钮可以提高无障碍功能和用户体验。
关闭对话框
您不需要 HTMLDialogElement.close()
方法来关闭对话框。您根本不需要 JavaScript。要在没有 JavaScript 的情况下关闭 <dialog>
,请包含一个带有 dialog 方法的表单,方法是在 <form>
上设置 method="dialog"
或在按钮上设置 formmethod="dialog"
。
当用户通过 dialog 方法提交时,用户输入数据的状态会保持。虽然有一个 submit 事件——表单会进行约束验证(除非设置了 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
属性返回 true
或 false
,具体取决于对话框是否可用于交互——而不是它是否是模态的。
虽然 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
属性。