了解非常有用的 details 和 summary 元素的工作原理以及在何处使用它们。
披露小部件是一种隐藏和显示内容的用户界面控件。如果您正在 web.dev 上阅读本文,并且您的视口宽度小于 106 em,则点击此段落上方的“本页内容”会显示本节的目录。如果您看不到,请缩小浏览器以查看此页面上的目录导航,它会显示为一个披露小部件。
手风琴图形用户界面是一系列垂直堆叠的披露小部件。手风琴 UI 的常见用例是许多网站上的“常见问题解答 (FAQ)”页面。手风琴 FAQ 包含一个可见问题列表;点击问题会展开或“披露”该问题的答案。
jQuery 自 2009 年以来就包含手风琴 UI 模式。最初的无 JavaScript 手风琴解决方案包括将每个 FAQ 问题设为一个 <label>
,后跟它标记的复选框,然后在复选框被选中时显示 <div>
答案。CSS 看起来像这样
#FAQ [type="checkbox"] + div.answer {
/* all the answer styles */
display: none;
}
#FAQ [type="checkbox"]:checked + div.answer {
display: block;
}
为什么要讲历史?披露小部件(例如手风琴)在没有 JavaScript 或表单控件 hack 的情况下是相对较新的添加;<details>
和 <summary>
元素自 2020 年 1 月起才在所有现代浏览器中获得完全支持。现在,您只需使用语义化 HTML 即可创建功能齐全但不太美观的披露小部件。<details>
和 <summary>
元素就是您所需要的:它们是处理展开和折叠内容的内置方法。当用户点击或轻触 <summary>
,或在 <summary>
获得焦点时释放 Enter 键时,父级 <details>
的内容会切换为可见!
与所有语义化内容一样,您可以逐步增强默认功能和外观。在本例中,添加了一点 CSS,但没有其他内容
您会注意到,这些 CodePen 不包含 JavaScript。
切换可见性:open
属性
<details>
元素是披露小部件容器。<summary>
是其父级 <details>
的摘要或图例。摘要始终显示,充当一个按钮,用于切换父级其余内容的显示。与 <summary>
交互会通过切换 <details>
元素的 open
属性来切换自标记摘要同级元素的显示。
open
属性是一个布尔属性。如果存在,无论值如何或是否缺少值,它都表示所有 <details>
内容都向用户显示。如果 open
属性不存在,则仅显示 <summary>
的内容。
由于 open
属性会随着用户与控件的交互而自动添加和删除,因此可以在 CSS 中使用它来根据元素的状态以不同的方式设置样式。
您可以使用多个 <details>
元素的列表创建一个手风琴,每个元素都有一个 <summary>
子元素。在 HTML 中省略 open
属性意味着 <details>
将全部折叠或关闭,页面加载时仅显示摘要标题;每个标题都是父级 <details>
中其余内容的开启器。如果在 HTML 中包含 open
属性,则 <details>
将在页面加载时呈现为展开状态,内容可见。
折叠状态下的隐藏内容在某些浏览器中可搜索,但在其他浏览器中不可搜索,即使折叠内容不是 DOM 的一部分。如果您在 Edge 或 Chrome 中搜索,包含搜索词的详细信息将展开以显示匹配项。此行为在 Firefox 或 Safari 中不会重现。
<summary>
必须是 <details>
元素的第一个子元素,表示父级 <details>
元素(它嵌套在其中)的其余内容的摘要、标题或图例。<summary>
元素的内容可以是任何标题内容、纯文本或可在段落中使用的 HTML。
切换摘要标记
在之前的两个 CodePen 中,您会注意到摘要的 inline-start 侧的箭头。披露小部件通常在屏幕上使用一个小三角形呈现,该三角形旋转(或扭曲)以指示打开/关闭状态,三角形旁边有一个标签。<summary>
元素的内容标记披露小部件。每个部分顶部的旋转箭头是在 <summary>
元素上设置的 ::marker
。与列表项类似,<summary>
元素支持 list-style
简写属性及其长写属性,包括 list-style-type
。您可以使用 CSS 设置披露三角形的样式,包括将使用的标记从三角形更改为任何其他项目符号类型,包括使用 list-style-image
的图像。
要应用其他样式,请使用类似于 details summary::marker
的选择器。::marker
伪元素仅接受有限数量的样式。删除 ::marker
并将其替换为更易于设置样式的 ::before
是一种常见做法,CSS 样式会根据 open 属性的存在(或缺失)稍微更改生成的内容的样式。您可以通过设置 list-style: none
或将标记的 content 设置为 none
来删除披露小部件图标,但始终包含视觉指示器,以告知有视觉障碍的用户摘要内容是一个切换按钮,激活后将显示和隐藏内容。
details summary::before {
/* all the styles */
}
details[open] summary::before {
/* changes applied when open only */
}
此示例删除了默认标记,并添加了生成的内容,以在详细信息关闭时创建 +
,在详细信息打开时创建 -
。
如果您希望详细信息块默认打开,请在开始 <details>
标记上包含 open
属性。您还可以在每个对话框之间添加空格,并过渡使用生成内容创建的标记的旋转,以改善外观
错误处理方式
如果您不包含 <summary>
,浏览器将为您创建一个:带有一个标记和单词“details”。此摘要是 shadow root 的一部分,因此不会应用作者 CSS 摘要样式。遗憾的是,Safari 不会将详细信息包含在 键盘焦点顺序 中。
如果您确实包含 <summary>
,但它不是 <details>
中的第一个元素,浏览器仍然会按应有的方式显示摘要。如果您在摘要中包含链接、标签或其他交互式元素,它也不会失败,但浏览器对交互式内容中的交互式内容的处理方式不同。例如,如果您在摘要中包含链接,某些浏览器会将摘要和链接都添加到默认的制表符顺序中,但其他浏览器默认情况下不会关注链接。如果您点击嵌套在 <summary>
中的 <label>
,某些浏览器会将焦点放在关联的表单控件上;其他浏览器会将焦点放在表单控件上,并切换 <details>
的打开或关闭状态。
HTMLDetailsElement
接口
与所有 HTML 元素一样,HTMLDetailsElement
从 HTMLElement
继承所有属性、方法和事件,并添加了 open
实例属性和 toggle
事件。HTMLDetailsElement.open
属性是一个布尔值,反映 open
HTML 属性,指示是否向用户显示元素的内容(不包括 <summary>
)。当 <details>
元素切换打开或关闭时,会触发 toggle 事件。您可以使用 addEventListener()
侦听此事件。
如果您想编写脚本以在用户打开任何其他详细信息时关闭已打开的详细信息,请使用 removeAttribute("open")
删除 open 属性
这是唯一使用 JavaScript 的示例。除了关闭其他已打开的披露小部件的此功能外,您可能不需要 JavaScript。
请记住,<details>
和 <summary>
可以进行大量样式设置,甚至可以用于 创建工具提示。但是,如果您要将这些语义元素用于本机语义不匹配的用例,请始终确保您 保持无障碍功能。在大多数情况下,HTML 默认情况下是无障碍的。我们作为开发人员的工作是确保我们的内容保持无障碍状态。
检查您的理解情况
测试您对 details 和 summary 的知识。
<summary>
必须是哪个元素的第一个子元素?
<p>
<details>
<fieldset>