List 列表创意样式

当您想到 list 列表时,脑海中会想到什么?最明显的例子就是购物清单,这是最简单的清单,即没有特定顺序的一系列商品。但是,我们在网络上以各种方式使用列表。想要举办一系列即将举行的音乐会?很可能是一个 list 列表。预订流程涉及多个步骤?可能是一个列表。还是图库中的图片?甚至,也可以看作是一系列带说明的图片。

在本文中,我们将深入介绍网络上可供我们使用的不同 HTML 列表类型以及何时使用这些列表类型,包括一些您可能不熟悉的属性。我们还将学习使用 CSS 设置样式的一些实用且富有创意的方式。

需要进行语义分组的项时,应使用 HTML 列表元素。辅助技术(例如屏幕阅读器)会通知用户有一个列表以及列表项数量。举个例子,想一想购物网站上的商品网格,了解这些信息会很有帮助。因此,使用列表元素可能是不错的选择。

在标记方面,我们提供了三种不同的列表元素供我们选择:

  • 无序列表
  • 有序列表
  • 说明列表

选择哪一个取决于用例。

当列表中的项不对应于任何特定顺序时,无序列表元素 (<ul>) 最为有用。默认情况下,此列表会显示为项目符号列表。例如购物清单,顺序无关紧要。

网络上比较常见的示例是导航菜单。构建菜单时,最好将 ul 封装在 nav 元素中,并使用标签来标识菜单,以便辅助技术。我们还应通过 aria-current 属性在菜单中确定当前页面:

<nav aria-label="Main">  
  <ul>  
    <li>  
      <a href="/page-1" aria-current="page">Menu item 1</a>  
    </li>  
    <li>  
      <a href="/page-2">Menu item 2</a>  
    </li>  
    <li>  
      <a href="/page-2">Menu item 2</a>  
    </li>  
      …  
    </ul>  
</nav>  

这篇关于菜单结构的文章概述了一些建议,旨在确保所有用户都能访问我们的导航菜单。

当项的顺序很重要(例如多步骤流程)时,有序列表元素 (<ol>) 是最佳选择。默认情况下,列表项有编号。例如一组指令,其中步骤必须按顺序完成。

[

<ol> 和 <ul> 元素都只能包含 <li> 元素作为其直接子级。

说明列表包含字词(<dt> 个元素)和说明(<dd>)。每个字词可以附带多条说明。可能的应用场景包括术语表,也可能是餐厅菜单。默认情况下,显示说明列表时不会显示任何标记,但浏览器往往会缩进 <dd> 元素。

在 HTML 中,可以使用 <div> 将字词及其随附的说明分组。这对于样式设置很有用,我们稍后会介绍。

<!-- This is valid --> 
<dl>  
    <dt>Term 1</dt>  
    <dd>This is the first description of the first term in the list</dd>  
    <dd>This is the second description of the first term in the list</dd>  
    <dt>Term 2</dt>  
    <dd>This is the description of the second term in the list</dd>  
</dl>

<!-- This is also valid --> 
<dl>  
    <div>  
        <dt>Term 1</dt>  
        <dd>This is the first description of the first term in the list</dd>  
        <dd>This is the second description of the first term in the list</dd>  
    </div>  
    <div>  
        <dt>Term 2</dt>  
        <dd>This is the description of the second term in the list</dd>  
    </div>  
</dl>  

列表最简单的一种用途是在正文块中。这些简单的列表通常不需要复杂的样式,但我们可能需要在某种程度上自定义有序或无序列表的标记,例如,使用品牌颜色,或者为项目符号使用自定义图片。我们可以使用 list-style 和 ::marker 伪元素执行很多操作!

除了为列表标记设置一些基本样式外,我们还可以创建循环项目符号。在这里,我们对 ::marker 伪元素的 content 值使用了三个不同的图片网址,这进一步增强了我们的购物清单示例的手写风格(而不是对全部图片都使用单张图片):

::marker {  
    content: url("/marker-1.svg") ' ';  
}

li:nth-child(3n)::marker {  
    content: url("/marker-2.svg") ' ';  
}

li:nth-child(3n - 1)::marker {  
    content: url("/marker-3.svg") ' ';  
}  

对于某些有序列表,我们可能希望使用计数器值,但向其附加另一个值。我们可以使用 list-item 计数器作为标记的 content 属性的值,并附加任何其他内容:

::marker {  
    content: counter(list-item) '🐈 ';  
}  

我们的计数器会自动递增 1,但可以通过为列表项设置 counter-increment 属性,允许计数器按不同的值递增(如果我们选择的话)。例如,这会使计数器每次递增 3:

li {  
    counter-increment: list-item 3;  
}  

我们还可以深入探讨计数器。CSS 列表、标记和计数器一文更详细地介绍了一些可能实现的功能。

有时,我们可能希望更好地控制标记的位置和样式。例如,无法使用 Flexbox 或网格定位标记,这有时会导致您需要进行其他对齐方式。::marker 针对样式公开了有限数量的 CSS 属性。如果设计需要基本样式以外的任何其他内容,我们可能更适合使用另一个伪元素。

有时,我们可能希望使用与默认样式完全不同的方式设置列表样式。导航菜单通常就是这样做的,例如,我们通常希望移除所有标记,并可能使用 flexbox 水平显示列表。常见做法是将 list-style 属性设置为 none。这意味着,无法再在 DOM 中访问标记伪元素。

在 ::marker 推出之前,设置 ::before 伪元素的样式是一种创建自定义列表标记的常见方式。但即便如此,它依然能让我们在需要时更灵活地设置视觉上的复杂列表样式。

与 ::marker 一样,我们可以使用 content 属性添加自己的自定义项目符号样式。与使用 ::marker 不同,我们需要执行一些手动定位,因为我们无法获得 list-style-position 提供的自动优势。但是,我们可以使用 Flexbox 相对轻松地定位它,这确实带来了更多对齐的可能性。例如,我们可以交替标记的位置:

如果要使用 ::before 元素设置有序列表的样式,我们还可能需要使用计数器来添加数字标记。

li::before {  
  counter-increment: list-item;  
  content: counter(list-item);  
}  

使用 ::before(而不是 ::marker)让我们可以完全访问用于自定义样式的 CSS 属性,还允许动画和转场效果,但对 ::marker 的支持有限。

有序列表元素接受一些可选属性,这些属性可以在各种用例中帮助我们。

如果我们要列出去年 10 大热门专辑的榜单,那么可以将排名从 10 降到 1。我们可以对此使用自定义计数器,并以负值递增。或者,我们也可以直接在 HTML 中使用 reversed 属性。我认为,在语义上,使用 reversed 属性而不是在 CSS 中使计数器按负值递增,除非计数器纯粹是为了呈现内容。如果 CSS 加载失败,您仍然会在 HTML 中看到正确倒计时。此外,我们还需要考虑屏幕阅读器如何解读列表。

观看 2021 年排名前 10 的专辑的演示。如果计数器仅通过 CSS 递增,则使用屏幕阅读器访问页面的用户可能会得出数字向上计数的结论,因此数字 10 实际上是排名第一。

在演示中,您可以看到,通过使用 reversed 属性,标记已经具有正确的值,而无需我们执行任何额外的操作!但是,如果我们使用 ::before 伪元素创建自定义列表标记,则需要调整计数器。我们只需要指示列表项计数器为负增量:

li::before {  
  counter-increment: list-item -1;  
  content: counter(list-item);  
}  

这在 Firefox 中已足够,但在 Chrome 和 Safari 中,标记会从 0 倒数至 -10。我们可以通过向列表中添加 start 属性来解决此问题。

利用 start 属性,我们可以指定列表应从哪个数值开始。例如,当您想要将列表拆分为多个组时,这种方法会很有用。

让我们以排名前 10 的专辑为例进行说明。实际上,可能我们想要对排名前 20 的专辑进行倒计时,但每组 10 张。这两个组之间还包含一些其他网页内容。

我们需要在 HTML 中创建两个单独的列表,但是如何确保计数器是正确的?根据我们当前的标记,两个列表都将从 10 倒数计时,这并不是我们想要的结果。不过,在 HTML 中,我们可以指定 start 属性值。如果我们向第一个列表添加值为 20 的 start 值,标记将再次自动更新!

<ol reversed start="20">  
  <li>...</li>  
  <li>...</li>  
  <li>...</li>  
</ol>  

正如之前的演示所示,多列布局有时非常适合我们的列表。通过设置列宽,我们可以确保列表能够自动做出响应,并且仅在有足够的空间时才显示在两列或更多列的上方。我们还可以在列之间设置间隔;为了进一步优化效果,可以添加样式化的 column-rule(使用类似于 border 属性的简写形式):

ol {  
    columns: 25rem;  
    column-gap: 7rem;  
    column-rule: 4px dotted turquoise;  
}  

使用列时,有时我们的列表项会出现不美观的中断,但这并不总是我们想要的效果。

我们可以通过对列表项使用 break-inside: avoid 来防止出现这些强制中断的情况:

li {  
    break-inside: avoid;  
}  

CSS 自定义属性为列表的样式设置提供了无限可能。如果我们知道列表项的索引,就可以用它来计算属性值。遗憾的是,目前在 CSS 中无法单独确定元素的索引(无论使用方式是否可用)。计数器仅允许我们在 content 属性中使用其值,不允许计算。

但是,我们可以在 HTML 的 style 属性中设置元素的索引,这可以使计算更加可行,尤其是当我们使用模板语言时。以下示例展示了如何使用 Nunjucks 进行设置:

<ol style="--length: items|length">  
  
</ol>  

Splitting.js 是一个在客户端执行类似功能的库。

使用自定义属性值,我们可以通过各种方式显示列表进度。一种方式可以是步骤列表的进度条。在此示例中,我们使用具有线性渐变的伪元素为每个项创建一个条形,以显示用户在列表中浏览的距离。

li::before {  
    --stop: calc(100% / var(--length) * var(--i));  
    --color1: deeppink;  
    --color2: pink;  

    content: '';  
    background: linear-gradient(to right, var(--color1) var(--stop), var(--color2) 0);  
}  

我们还可以使用 hsl() 颜色函数在列表显示时调整色调。我们可以使用自定义属性计算 hue 值。

如前所述,我们可以选择将术语及其定义封装在 dl 的 div 中,从而为我们提供更多样式选项。例如,我们可能希望将列表显示为网格。如果在列表中设置 display: grid,并且没有将每个组括起来的封装容器 div,则意味着我们的字词和说明会被放置在不同的网格单元格中。这有时很有用,如下例所示,其中包含一个馅饼菜单及相关说明。

我们可以在列表上定义一个网格,并确保字词和说明始终按列对齐,且列宽由最长期限决定。

另一方面,如果我们想要按照卡片式的说明对字词进行分组,封装容器 <div> 会非常有用。

阅读余下内容
 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号