HTML 列表很无聊。 他们不 do 很多,所以尽管它们被广泛使用,但我们并没有真正考虑它们。 我们仍然能够做我们一直做的同样的事情来定制它们,比如移除标记、颠倒顺序和制作定制计数器。
但是,在使用列表时需要了解一些“较新”的东西——包括危险。 危险大多是轻微的,但比你想象的要普遍得多。 我们将讨论这些,加上我们可以用列表做的一些新事情,甚至是处理旧解决方案的新方法。
澄清一下,这些是我们正在谈论的 HTML 元素:
- 有序列表
- 无序列表
- 说明列表
- 交互式列表
有序列表、无序列表和交互式列表包含列表项 (
) 根据我们正在处理的列表类型显示。 有序列表(
) 在列表项旁边显示数字。 无序列表 (
) 和菜单元素 (
) 在列表项旁边显示项目符号。 我们称这些为“列表标记”,并且 他们甚至可以设计风格 使用 ::标记 伪元素。 描述列表使用描述术语 (
) 和描述细节 (
) 代替
并且没有列表标记。 它们应该用于显示元数据和词汇表,但我不能说我在野外见过它们。
让我们从简单的事情开始——如何正确(至少在我看来)重置列表样式。 在那之后,我们将先看看几个可访问性问题,然后再阐明难以捉摸的问题
元素,你可能会惊讶地发现……实际上也是一种列表!
重置列表样式
浏览器会自动应用自己的用户代理样式,以帮助开箱即用的列表视觉结构。 那太好了! 但是如果我们想从没有样式意见的空白板开始,那么我们必须先重置这些样式。
例如,我们可以很容易地删除列表项旁边的标记。 这里没有什么新鲜事:
/* Zap all list markers! */
ol, ul, menu {
list-style: none;
}
但是现代 CSS 有新的方法来帮助我们定位特定的列表实例。 假设我们要清除所有列表中的标记,除非这些列表出现在 长篇内容,如文章. 如果我们结合新的 CSS 伪类函数的力量 :where()
和 :not()
,我们可以隔离这些实例并在这些情况下允许标记:
/* Where there are lists that are not articles where there are lists... */
:where(ol, ul, menu):not(article :where(ol, ul, menu)) {
list-style: none;
}
为什么使用 :where()
而不是 :is()
? 的特异性 :where()
始终为零,而 :is()
采用其选择器列表中最具体的元素的特殊性。 所以,使用 :where()
是一种不太有效的覆盖事物的方式,并且可以很容易地被覆盖。
UA 样式还应用填充以将列表项的内容与其标记隔开。 同样,在某些情况下,这是一个非常好的开箱即用功能,但是如果我们已经像上面那样删除了列表标记,那么我们也可以删除该填充。 这是另一个案例 :where()
:
:where(ol, ul, menu) {
padding-left: 0; /* or padding-inline-start */
}
好的,这将防止无标记列表项出现在空间中。 但是我们有点把婴儿和洗澡水一起倒掉,并在所有情况下都去掉了填充物,包括我们之前在
. 所以,现在那些带有标记的列表有点悬在内容框的边缘。
请注意,UA 样式应用了额外的 40px
到
元件。
所以我们要做的是防止列表标记“挂”在容器外面。 我们可以用 list-style-position
属性:
或者不是……也许归结为风格偏好?
较新的列表可访问性问题
不幸的是,在列表方面存在一些可访问性问题——即使在更现代的时代也是如此。 一个问题是应用的结果 list-style: none;
正如我们在重置 UA 样式时所做的那样。
简而言之,Safari 才不是 读取带有样式的有序和无序列表 list-style: none
作为实际列表,例如使用屏幕阅读器浏览内容时。 换句话说,删除标记也会删除列表的语义。 这 修复此修复 它应用一个 唱腔 list
名单上的角色和 listitem
对列表项的作用 所以屏幕阅读器会把它们捡起来:
- ...
- ...
- ...
- ...
- ...
- ...
奇怪, Safari 认为这是一项功能 而不是错误。 基本上,用户会报告屏幕阅读器宣布了太多列表(因为开发人员倾向于过度使用它们),所以现在,只有那些 role="list"
由屏幕阅读器宣布,毕竟这实际上并不奇怪。 斯科特·奥哈拉 有一个 详细的清单 这一切是如何发生的。
第二个可访问性问题不是我们自己造成的(万岁!)。 所以,你知道怎么做 你应该 添加 aria-label
至
没有标题的元素? 好吧,有时对不包含帮助描述列表的标题元素的列表执行相同的操作是有意义的。
Grocery list
你绝对 别 必须使用任何一种方法。 使用标题或 ARIA 标签只是添加上下文,而不是必需的 - 请务必使用屏幕阅读器测试您的网站,并根据情况提供最佳用户体验。
在一些相关的新闻中,Eric Bailey 写了一篇关于 他为什么以及如何考虑 aria-label
成为一种代码味道.
也是列表吗?
好的,所以,您可能想知道所有
我一直在代码示例中加入的元素。 其实超级简单; 菜单是无序列表,只是它们用于交互式项目。 它们甚至作为无序列表暴露给可访问性树。
在语义网的早期,我错误地认为菜单就像
在相信它们是用于上下文菜单(或“工具栏”作为 规范说) 因为那是 HTML 规范的早期版本所说的。 (MDN 有一篇有趣的文章 在所有与相关的已弃用的东西上
如果你有兴趣的话。)
然而,今天,这是使用菜单的语义方式:
就个人而言,我认为有一些很好的用例
. 最后一个示例显示了一个包含在标签中的社交分享按钮列表
元素,值得注意的方面是“分享文章”标签贡献了大量上下文,有助于描述按钮的作用。
菜单是绝对必要的吗? 不,他们是 HTML 地标? 当然不。 但如果你享受更少,他们就在那里
s 并且您觉得该组件可以使用
aria-label
额外的上下文。
还有别的吗?
是的,还有前面提到的
(描述列表)元素,但是, MDN 似乎不考虑它们列表 以同样的方式——它是一个包含术语的组列表——我不能说我真的看到它们在使用中。 根据 MDN,它们应该用于元数据、词汇表和其他类型的键值对。 我只是避免使用它们,因为所有屏幕阅读器都会以不同的方式宣布它们。
但是,我们不要以消极的方式结束事情。 这是您可以使用列表做的超酷事情的列表: