掌握现代网页内容切换技巧:告别display: none
!
工欲善其事,必先利其器。
——亚伯拉罕·马斯洛
习惯使用熟悉的工具很容易。对于内容切换,你可能习惯使用display: none
或opacity: 0
,并辅以一些JavaScript代码。但如今的网页技术更加现代化,是时候全面了解各种内容切换方法了:哪些原生API得到支持,它们的优缺点是什么,以及你可能不知道的一些细节(例如伪元素和其他不明显的内容)。
让我们一起探讨一下<details></details>
和<summary></summary>
元素、Dialog API、Popover API等等。我们将根据你的需求,探讨何时使用每种方法。模态还是非模态?JavaScript还是纯HTML/CSS?别担心,我们将一一讲解。
<details></details>
和<summary></summary>
元素应用场景:以易于访问的方式总结内容,同时允许独立或作为手风琴式组件切换内容细节。
2024年12月12日更新:Chrome博客上的一篇新文章展示了使用<details></details>
的几种更有趣的方法,包括动画图库和部分打开的<details></details>
(可以选择使用calc-size
进行动画处理)。
按照发布顺序,<details></details>
和<summary></summary>
元素标志着我们第一次能够在不使用JavaScript或奇特的复选框技巧的情况下切换内容。但缺乏浏览器支持显然会阻碍新功能的普及,特别是这个功能最初缺乏键盘可访问性。如果你从2011年Chrome 12版本发布以来就没有使用过它,我能够理解。眼不见心不烦,对吧?
以下是重点:
appearance: none
等属性即可完全进行样式设置。<details></details>
元素来创建一个手风琴式组件。<details></details>
元素的标记你需要的是:
<details><summary>内容摘要(始终可见)</summary> 内容(单击摘要时切换可见性) </details>
在后台,内容被包装在一个伪元素中,从2024年开始,我们可以使用::details-content
选择它。此外,还有一个::marker
伪元素指示<details></details>
是打开还是关闭,我们可以自定义它。
考虑到这一点,<details></details>
在后台实际上是这样的:
<details><summary>内容摘要(始终可见)</summary> 内容(单击摘要时切换可见性) </details>
要使<details></details>
默认打开,请为<details></details>
添加open
属性,这与<details></details>
打开时后台发生的情况相同。
<details><summary><::marker></::marker>内容摘要(始终可见)</summary><::details-content> 内容(单击摘要时切换可见性) </::details-content></details>
<details></details>
元素的样式设置说实话:你可能只想去掉那个烦人的标记。你可以通过将<summary></summary>
的display
属性设置为除list-item
以外的任何值来实现:
<details open=""> ... </details>
或者,你可以修改标记。事实上,下面的示例使用了Font Awesome将其替换为另一个图标,但请记住::marker
不支持许多属性。最灵活的解决方法是用一个元素包装<summary></summary>
的内容,然后在CSS中选择它。
summary { display: block; /* 或任何其他非 list-item 的值 */ }
<details><summary>内容摘要</summary> 内容 </details>
<details></details>
元素创建手风琴式组件要创建手风琴式组件,请使用name
属性为多个<details></details>
元素命名,并使用匹配的值(类似于实现单选按钮的方式):
details { /* 标记 */ summary::marker { content: "\f150"; font-family: "Font Awesome 6 Free"; } /* <details>打开时的标记 */ &[open] summary::marker { content: "\f151"; } /* 因为 ::marker 不支持许多属性 */ summary span { margin-left: 1ch; display: inline-block; } }</details>
使用一个包装器,我们甚至可以将它们变成水平选项卡:
<details name="starWars" open=""><summary>前传</summary><ul> <li>第一集:幽灵的威胁</li> <li>第二集:克隆人的进攻</li> <li>第三集:西斯的复仇</li> </ul></details><details name="starWars"><summary>原版</summary><ul> <li>第四集:新希望</li> <li>第五集:帝国反击战</li> <li>第六集:绝地归来</li> </ul></details><details name="starWars"><summary>续集</summary><ul> <li>第七集:原力觉醒</li> <li>第八集:最后的绝地武士</li> <li>第九集:天行者的崛起</li> </ul></details>
<div> <details name="starWars" open=""> ... </details><details name="starWars"> ... </details><details name="starWars"> ... </details> </div>
……或者,使用2024年的Anchor Positioning API,创建垂直选项卡(相同的HTML):
div { gap: 1ch; display: flex; position: relative; details { min-height: 106px; /* 防止内容偏移 */ &[open] summary, &[open]::details-content { background: #eee; } &[open]::details-content { left: 0; position: absolute; } } }
如果你想了解一下我们如何使用CSS中的Popover API,可以查看John Rhea的文章,他在文章中仅仅使用<details></details>
元素就制作了一个互动游戏!
想要添加一些JavaScript功能?
div { display: inline-grid; anchor-name: --wrapper; details[open] { summary, &::details-content { background: #eee; } &::details-content { position: absolute; position-anchor: --wrapper; top: anchor(top); left: anchor(right); } } }
<details></details>
元素只要遵循一些规则,<details></details>
元素就是可访问的。例如,<summary></summary>
基本上是一个<label></label>
,这意味着当它获得焦点时,屏幕阅读器会宣布其内容。如果没有<summary></summary>
或<summary></summary>
不是<details></details>
的直接子元素,则用户代理会为你创建一个标签,通常在视觉上和辅助技术中都显示为“Details”。较旧的浏览器可能坚持要求它是第一个子元素,因此最好将其设置为第一个子元素。
此外,<summary></summary>
具有按钮的角色,因此在<button></button>
中无效的内容在<summary></summary>
中也是无效的。这包括标题,因此你可以将<summary></summary>
的样式设置为标题,但你不能实际将标题插入<summary></summary>
中。
剩余内容因篇幅限制,无法全部翻译。请提供其他部分,我将尽力翻译。
以上是切换内容的不同(现代)方式的详细内容。更多信息请关注PHP中文网其他相关文章!