如果真的有 CSS 技巧的话,这绝对算一个!@ShadowShahriar 创建了一个 CodePen 演示,它使用伪元素在以行内显示的列表项之间放置逗号,结果是一个自然美观的完整句子,带有正确的标点符号。
它是如何工作的
技巧是什么?首先,是要将一个无序列表设置为一个没有标记或间距的行内元素。
ul {
padding: 0;
margin: 0;
display: inline;
list-style-type: none;
}
接下来,我们将列表项以行内方式显示,以便它们在句子中自然地作为文本流动。
li {
display: inline;
}
然后,我们通过选择它们的::after
伪元素并在其content
属性中设置逗号(,
)值,在列表项之间添加逗号。
li::after{
content: var(--separator);
}
哦,但是等等!那个老式的牛津逗号怎么办?使用:nth-last-of-type()
选择倒数第二个列表项,并在最后一个列表项之前的::after
伪元素的content
属性中设置为", and"
。
li:nth-last-of-type(2)::after{
content: ", and ";
}
我们还没有完成。@ShadowShahriar 考虑了一种只有两个项目的极端情况。我们只需要在这两个项目之间显示一个“and”,所以
li:first-of-type:nth-last-of-type(2)::after {
content: " and ";
}
我不得不在Selectors Explained上查找以确保我正确理解了它。也就是说
after
伪元素……属于一个
<li>
元素,前提是它是其父元素中其类型的第一个元素,并且是其父元素中从末尾开始的第n个类型(公式)。
真是太拗口了!最后的润色是在列表末尾添加一个句号。
li:last-of-type::after {
content: ".";
}
使用自定义属性
我们刚刚查看了实际代码的简化版本。@ShadowShahriar 做了一件不错的事情,将逗号和“and”设置为自定义属性。
ul {
--separator: ",";
--connector: "and";
padding: 0;
margin: 0;
display: inline;
list-style-type: none;
}
这样,我们以后就可以将它们替换为其他分隔列表项的方式。不错的技巧。
这个技巧不仅因为它巧妙地使用了伪元素技巧,还因为它简单易用而吸引了我的注意。它以一种支持语义 HTML 的方式使用了久经考验的 CSS 原则——不需要额外的类、元素甚至 JavaScript 来帮助操作事物。这几乎让我怀疑 HTML 是否可以使用某种内联列表元素(<il>
有人吗???)来帮助支持句子传达列表项而不破坏段落。
虽然完全不同,但它也让我想起了这个非常花哨的技巧,它在换行符出现时处理分隔符的使用。
https://chriskirknielsen.com/blog/inline-lists-with-conditional-separators/
真的很棒!遗憾的是,这种方法的一个不幸的副作用是,当您突出显示文本时,逗号和“and”将不会包含在内。
例如,三个项目的示例变为
当您复制粘贴它时。
尽管如此,这在您不需要选择文本的上下文中仍然很有用。
复制文本时,最后一个和倒数第二个元素将合并在一起。
时光飞逝。我在 2003 年讨论过这个问题,并在不考虑 IE 的情况下随时使用它。从那时起,对于面包屑导航,这已成为首选方法。
最终效果很棒。我想知道屏幕阅读器是否比纯文本更容易解析它。除了看起来不错之外,这还有其他优势吗?
辅助技术会忽略伪元素,因此它们会将列表读取为常规列表元素,而不会进行任何更改。它将仅对有视力的人员具有视觉效果。
事实上,它可能会——我不能确定——导致视力障碍用户感到困惑,因为他们可能能够分辨出一个句子,但他们的辅助技术将其解释为一系列项目。
虽然我很欣赏这是一种巧妙的方法,但我不知道为什么要这样做。
我无法理解其原因
“有时您可能希望在段落或语句中显示列表项。”
为什么不在段落或语句中列出项目?当不需要时,为什么要费心使用额外的标记和样式?
这个技巧很巧妙。是什么促使您在这里添加额外的标记?从语义上讲,这可能是有道理的,但是您是否测试过不同的屏幕阅读器如何使用伪选择器宣布这些列表?