Skip to content
This page has been auto-translated and may contain errors.View in English

列表

docs.scrimba.com

网页中出人意料的大部分内容其实都是列表:导航菜单、搜索结果、产品网格、食谱的材料清单、重置密码的步骤。只要内容是一组相关项目,HTML 就有一个元素来表示这一点,使用它意味着浏览器和任何使用辅助软件的人都知道这些项目属于一起。

无序列表

当项目的顺序不重要时,你使用**无序列表**。想象一个购物清单:牛奶、面包、鸡蛋。你先写哪个都不重要,它们就是一组聚集在一起的东西。

你用两个标签来构建它。<ul> 标签包裹整个列表,每个项目放在它自己的 <li> 标签内("列表项"):

html
<ul>
  <li>牛奶</li>
  <li>面包</li>
  <li>鸡蛋</li>
</ul>

浏览器在每个项目前面显示一个项目符号,每个项目单独占一行。你没有自己添加项目符号或换行符,浏览器这样做是因为你告诉它这是一个列表。

无序列表是一组项目,其中顺序没有意义。<ul> 元素是容器,每个直接子元素都是一个 <li> 元素,保存一个项目:

html
<ul>
  <li>免费配送超过 £40</li>
  <li>30 天内可退货</li>
  <li>两年保修</li>
</ul>

有一条规则要弄清楚:<ul> 的直接子元素中只允许 <li>。你不应该把 <p><div> 直接放在 <ul> 里。如果你想在项目中放一个段落或链接,它应该放在 <li> 中,它可以保存任何你喜欢的内容。

项目符号和缩进是浏览器的默认样式,不是含义的一部分。当你学习 CSS 时,你可以自由地改变或删除它们,列表在下面仍然是一个列表。

无序列表标记一组项目,其顺序不重要。<ul> 是容器,每个项目是一个 <li><ul> 的唯一允许的直接子元素是 <li> 元素(以及脚本支持元素如 <template>),所以在 <ul> 和其项目之间放置一个裸露的 <div> 是无效的,解析器不会将其视为列表的一部分。

html
<ul>
  <li>免费配送超过 £40</li>
  <li>30 天内可退货</li>
  <li>两年保修</li>
</ul>

项目符号和缩进是浏览器内置样式表的表现性默认值,不是语义;list-style: none 删除它们而不改变元素的含义。这种区分很重要,因为含义存在于元素中,项目符号只是表面。辅助软件(屏幕阅读器等工具的总称,为看不到页面的人大声读出页面)读取的是结构,而不是标记:它宣布列表正在开始以及它包含多少项目。我们在关于嵌套的"深度潜水"中回到这个通知的好处。

Juno无序列表 对于顺序不重要的列表使用 <ul>,并将每个项目包裹在它自己的 <li> 中。浏览器为你添加项目符号和换行符,所以你永远不需要手动输入那些。我花了一段时间才相信这一点,我总是想自己添加点。
Juno无序列表<ul> 是容器,其唯一的直接子元素是 <li> 项目。任何更复杂的内容(链接、段落)放在 <li> 中,永远不要松散地放在 <ul> 中。项目符号是默认样式,你稍后可以更改,所以按照含义选择元素,而不是外观。
Juno无序列表<ul> 只接受 <li> 作为直接子元素,所以里面有一个多余的 <div> 是无效的标记。项目符号来自浏览器样式表,不是语义,所以 list-style: none 删除点并保留列表。这种区分是为什么屏幕阅读器在你的 CSS 隐藏标记后仍然可以计数项目的全部原因。

有序列表及其属性

有时顺序是关键。食谱中的步骤、比赛中的位置、你依次遵循的说明。对于这些,你使用**有序列表**,它为你编号项目。

它的工作方式完全像无序列表,但容器是 <ol> 而不是 <ul>

html
<ol>
  <li>将烤箱预热到 180°C</li>
  <li>混合面粉和糖</li>
  <li>倒入锡盒中,烘烤 25 分钟</li>
</ol>

现在浏览器在项目前面显示 1、2、3 而不是项目符号。如果你稍后在中间添加一个新步骤,数字会自动重新编号。你永远不需要输入数字,这就是使用 <ol> 的意义。

有序列表用于顺序有意义的项目。与 <ul> 结构相同,将容器切换为 <ol>,浏览器会自动编号每个 <li>。因为数字是生成的,插入或删除项目会自动重新编号其余项目。

<ol> 有三个值得了解的属性。start 设置列表开始的数字:

html
<ol start="4">
  <li>打蛋</li>
  <li>折入面粉</li>
</ol>

该列表运行 4、5。当列表在其他内容将其分成两部分后继续时很有用。

type 改变编号样式:1 用于数字(默认),Aa 用于字母,Ii 用于罗马数字。

html
<ol type="a">
  <li>收集你的证据</li>
  <li>撰写摘要</li>
</ol>

该列表运行 a、b 而不是 1、2。reversed 从高到低倒计数,适合倒计时或从下往上读的前五名排名:

html
<ol reversed>
  <li>铜牌</li>
  <li>银牌</li>
  <li>金牌</li>
</ol>

有序列表标记顺序有意义的项目;<ol> 从生成的值对每个 <li> 进行编号,所以序数永远不是你输入的内容,并且当项目移动时保持正确。

三个属性控制编号。start 将第一个序数设置为整数,无论显示样式如何,所以罗马数字列表上的 start="4" 从 iv 开始。type 设置标记样式:1AaIireversed(布尔属性,意味着其存在本身就是值,没有要设置的东西)从项目数倒计数到 1。

html
<ol type="I" start="4" reversed>
  <li>基础</li>
  <li>推出</li>
  <li>审查</li>
</ol>

有一个区别样式可以隐藏。type 只改变标记的绘制方式;宣布给辅助软件并由 start 使用的仍然总是基础整数。所以用字母样式化的列表在底层仍然是位置 1、2、3。当序数本身是内容的一部分时,一个为引用编号的法律条款,宁可让 <ol> 拥有数字,也不要在文本中硬编码它,因为 <li> 中硬编码的 "3." 不会重新编号,屏幕阅读器会读两次:一次作为生成的标记,一次作为文本。还有一个值得了解的控制:单个 <li> 上的 value 属性覆盖该项目的数字,列表从那里继续计数。

Juno有序列表及其属性 当顺序重要时(如食谱中的步骤)使用 <ol>,浏览器为你编号项目。添加或删除一个步骤,数字会自动修复,所以你永远不需要手动输入 1.2.。与之前相同的 <li> 项目,只是不同的容器。
Juno有序列表及其属性<ol> 给你三个方便的属性:start 以 1 以外的数字开始,type 用字母或罗马数字代替数字,以及 reversed 倒计数。它们都仍然让浏览器生成数字,这就是你使用有序列表的原因。
Juno有序列表及其属性type 只重新样式化标记;其后面的值,start 使用的值和辅助技术读取的值,总是整数。所以不要手动输入 "3." 到 <li> 中,否则它不会重新编号,屏幕阅读器会说两次数字。让 <ol> 拥有计数,当你需要调整一个项目时在单个 <li> 上使用 value

描述列表

有第三种列表类型,用于当每个项目真的是一对时:一个词和它的意思,一个标签和它的值。词汇表是最清楚的例子,每个术语后面跟着它的含义。

这是一个**描述列表**,它使用三个标签。<dl> 包裹整个东西,<dt> 保存每个术语,<dd> 保存与其相关的描述:

html
<dl>
  <dt>HTML</dt>
  <dd>描述页面结构的语言。</dd>
  <dt>CSS</dt>
  <dd>描述页面外观的语言。</dd>
</dl>

浏览器在每个术语下面缩进显示每个描述,所以配对一目了然。把 "dt" 想象为你定义的词,把 "dd" 想象为定义。

当每个项目是一个配对而不是独立的东西时,描述列表比 <ul><ol> 更合适。它由三个元素组成:<dl> 是容器,<dt> 是术语,<dd> 是与其关联的描述。

html
<dl>
  <dt>作者</dt>
  <dd>王小芳</dd>
  <dt>发布时间</dt>
  <dd>2024 年 3 月 14 日</dd>
  <dt>阅读时间</dt>
  <dd>6 分钟</dd>
</dl>

该示例显示了除词汇表外的第二个主要用途:键/值元数据,一组标签及其值。分组是灵活的。一个 <dt> 可以后跟多个 <dd> 元素,当一个术语有多个描述时,多个 <dt> 元素可以共享单个 <dd> 当几个术语意思相同时。当你的内容自然是 "这个,及其详情" 时使用 <dl>,当项目独立存在时使用 <ul><ol>

描述列表将名称与值关联起来。<dl> 是容器;<dt> 是术语(名称);<dd> 是描述(值)。浏览器和辅助软件理解的结构是一系列组,其中一个组是一个或多个 <dt> 元素后跟一个或多个 <dd> 元素。

html
<dl>
  <dt>存储</dt>
  <dt>容量</dt>
  <dd>256 GB SSD</dd>

  <dt>颜色</dt>
  <dd>石墨色</dd>
  <dd>银色</dd>
</dl>

这种灵活性是关键:许多术语可以共享一个描述,一个术语可以有许多描述。有两个实用的应用脱颖而出。第一个是术语和定义内容,比如词汇表。第二个是键/值元数据,一个规格表或一组文章详情,其中每个标签与其值配对;<dl> 说 "这些是名称/值对" 的方式是 <div> 堆栈永远做不到的。注意命名怪癖:<dt><dd> 历史上代表 "definition term"(定义术语)和 "definition description"(定义描述),但现代规范故意将它们拓宽到任何名称/值关联,而不仅仅是字典定义。如果你的内容是同等的平面列表,没有配对,<dl> 是错误的工具,<ul> 是诚实的工具。

Juno描述列表 描述列表用于配对:术语及其含义。在整个东西周围使用 <dl>,对每个术语使用 <dt>,对其后的描述使用 <dd>。词汇表是你要记住的图片,术语然后定义,术语然后定义。
Juno描述列表 当每个项目是一个配对时,一个术语及其详情或一个标签及其值,而不是一组同等项目时,选择 <dl>。分组很灵活:一个 <dt> 可以接受多个 <dd>,多个 <dt> 可以共享一个 <dd>。作者和日期这样的键/值元数据是它在词汇表之外占有一席之地的地方。
Juno描述列表<dl> 表示名称/值对,规范将 <dt><dd> 从字典定义扩展到任何标签和值,所以元数据是合理的。许多术语可以共享一个值,一个术语可以持有许多值,<div> 墙永远无法表达。如果项目是没有什么可配对的同等项目,那就是 <ul>,不是 <dl>

嵌套列表

列表可以放在其他列表中。一个菜单可能有 "饮料" 下面有热和冷的选项,每一个都有它自己的选择。把一个列表放在另一个列表中称为**嵌套**。

要点是要做对:内部列表放在 <li> 内,不是浮动在项目之间。你把整个 <ul>(或 <ol>)放在它属于的列表项中:

html
<ul>
  <li>饮料
    <ul>
      <li>咖啡</li>
      <li>茶</li>
    </ul>
  </li>
  <li>零食</li>
</ul>

"咖啡" 和 "茶" 是 "饮料" 的一部分,所以它们的小列表存在于 "饮料" 项中。浏览器缩进内部列表,所以你可以看到它属于上面的项目。

为了显示某些项目属于另一个项目,你在列表中嵌套一个列表。保持有效的规则:嵌套列表是 <li> 的子元素,永远不是外部 <ul><ol> 的直接子元素。内部列表坐在它展开的项目内。

html
<ul>
  <li>水果
    <ul>
      <li>苹果</li>
      <li>香蕉</li>
    </ul>
  </li>
  <li>蔬菜
    <ul>
      <li>胡萝卜</li>
      <li>菠菜</li>
    </ul>
  </li>
</ul>

在嵌套时你可以混合类型,一个 <ol><ul> 中或反之,并根据内容真实情况嵌套得很深。你在真实代码中遇到嵌套列表最常见的地方是带子菜单的导航菜单:顶级列表的部分,每个都有它自己的页面列表在其 <li> 中。

嵌套是表达层级的方式:子列表放在它属于的 <li> 中,永远不是作为父 <ul><ol> 的直接子元素。做错了(一个 <ul> 直接坐在另一个 <ul> 中)是无效的,解析器的恢复不保证与你的图片匹配。

嵌套也是结构为看不到缩进的人付出成果的地方。屏幕阅读器宣布列表、其项目计数和当进入每个级别时的嵌套深度:"列表,三个项目",然后在子列表上 "列表,两个项目",它告诉用户什么时候再次移出。这种连续的评论是缩进你的眼睛免费读取的非视觉等价物,只有当嵌套是真实标记而不是用间距推动的项目时才存在。

这导致了对任何列表的诚实测试。导航菜单(一组在页面之间移动访问者的链接,出现在大多数网站顶部的行)目的地列表,所以语义正确的标记是一个 <ul> 链接,通常在一个标记区域为导航的 <nav> 元素中。当内容是一组相关项目时使用真实列表,无论 CSS 稍后使其看起来像什么。当它不是时不要使用:通过将无关块包裹在 <li> 中来伪造它们之间的间隙以借用列表间距告诉辅助软件 "这三样东西是三的组" 当它们不是时。标记可以隐藏,布局可以是任何东西;<ul><ol><dl> 的选择应该总是回答内容诚实上是什么。

Juno嵌套列表 要把一个列表放在一个列表中,将内部列表放到它属于的 <li> 中,而不是松散地放在项目之间。浏览器缩进它,所以你可以看到它是上面项目的一部分。那个在 <li> 中的规则是这里要记住的唯一东西。
Juno嵌套列表 嵌套列表总是 <li> 的子元素,永远不是外部 <ul><ol> 的直接子元素。你可以在 <ul> 中混合 <ol> 并根据内容真实情况深入。带子菜单的导航菜单是你会最常遇到这个的地方,所以现在花时间适应是值得的。
Juno嵌套列表 把子列表放在它的 <li> 中,因为屏幕阅读器读出项目计数和嵌套深度,这种口头结构是为看不到缩进的人替代缩进的东西。导航菜单真的是链接列表,所以将其标记为一个;不要通过将无关块包裹在 <li> 中来借用间距。让元素说出内容诚实上是什么,之后随意样式化它。