CSS 教程 / CSS 段落与列表样式:行距、缩进和列表标记

CSS 控制段落的对齐、缩进、行距和边距,而不改变文本的含义。对于列表,标记样式和位置会影响换行项的外观,而 HTML 仍然提供列表的结构和排序。

将行距与段落间距分开

.article p {
  line-height: 1.65;
  margin-block: 0 1.2em;
}

增大 line-height(参见 CSS 字体、字体大小和行高),同一段落内的行距会增大。增加 margin-block 会增加段落框与后续内容之间的外边距。在短段落中交替使用两者可能看起来没问题,但在长段落中可能导致行间距过大。

margin-block: 0 1.2em 将块起始边距设置为零,块结束边距设置为 1.2em。在这个横向书写示例中,它们对应的是上方和下方。纵向书写会改变实际方向。在这里,em 使用段落自身的字体大小。请参见 MDN:margin-block。

浏览器提供默认的段落和列表边距。请有意覆盖它们,以区分这些默认值与您自己设置的间距。相邻的垂直块边距可能会折叠,而不是相加。此示例将段落的起始边距设置为零,并通过结束边距控制间隙。有关详细信息,请参见 CSS 盒模型:内容、内边距、边框和外边距 。

比较文本对齐和首行缩进

.article p { text-align: start; }

.article .intro { text-indent: 1.5em; }

text-align 决定行内文本的对齐方式。start 是文本流的开始,在从左到右的基本文档中位于左侧。这不是将整个段落框移动到屏幕中央的属性。长的居中对齐描述每行的起始位置不同,因此首先为正文选择易于阅读的对齐方式。

text-indent: 1.5em 缩进第一行的开头,而不是每一行。完整示例将 class="intro" 放在整个示例的第一段中,这样你可以观察其效果。如果你想缩进整个段落,需要查看其他设置,例如内边距。更改对齐方式、缩进和边距,并对比哪些部分会移动。

定位列表标记和换行文本

对于有顺序的流程使用 ol,对于顺序不重要的项目使用 ul。在 CSS 中将数字形状更改为点并不会改变原始的 HTML 结构。先选择内容的含义,然后再调整显示方式。

属性 控制内容 长条目中需要关注的内容
list-style-type 点和数字等显示符号的类型 你能理解顺序的含义吗?
list-style-position: outside 在内容框外显示符号 第二行是否与第一行正文的起点对齐?
list-style-position: inside 在第一行中包含符号 第二行的起点是否延伸到标记所在区域?
padding-inline-start 文本流开头的内边距 符号是否被切断或未与文本连接?

使用 outside 时,列表标记位于内容框外,因此需要在列表的行内起始位置预留空间。在此从左到右的示例中,padding-inline-start: 1.6em 提供左侧内边距。使用 inside 时,标记占据第一行的空间;随后的行可以延伸到其位置下方。比较真实的换行项目。

移除列表标记也需要进行可访问性检查。当其在 nav 外部时,Safari 可能会从可访问性树中遗漏使用 list-style: none 的列表。在需要保留列表语义时,请考虑 role="list"。本课程的完整示例保持其标记。参见 MDN:list-style。

将项目间距与行间距分开

.article li + li { margin-block-start: 0.45em; }

li + li 选择紧跟在另一个 li 之后的 li。这条规则从第二项起,在每一项前添加间距;第一项前不会因此增加间距。项目中跨多行的部分由列表继承的行高控制。如果仅因为内容密集而增加项目之间的间距,项目内的句子可能仍然显得狭窄。

运行完整的段落和列表示例

将下面的代码以 UTF-8 保存到 paragraphs.html 文件中并打开它。两个无序列表的内容相同,便于只比较标记位置和换行对齐的变化。首行缩进和有序列表也在同一文件中检查。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Comparing paragraphs and lists</title>
  <style>
    body { margin: 24px; font-family: sans-serif; color: #333; }
    .article { max-width: 65ch; }
    .article p { line-height: 1.65; margin-block: 0 1.2em; text-align: start; }
    .article .intro { text-indent: 1.5em; }
    .article ul, .article ol { padding-inline-start: 1.6em; margin-block: 0 1.2em; line-height: 1.65; }
    .article li + li { margin-block-start: 0.45em; }
    .outside { list-style-position: outside; }
    .inside { list-style-position: inside; }
    ol { list-style-type: decimal; }
  </style>
</head>
<body>
  <main class="article">
    <h1>Small Garden visitor guide</h1>
    <p class="intro">If this is your first visit, check the signs first. This paragraph has a first-line indent. When the text wraps, the remaining lines return to the normal paragraph edge.</p>
    <p>Use line-height for spacing between lines and margin for spacing between paragraphs. Narrow the window and check readability as the text wraps onto more lines.</p>
    <h2>outside list</h2>
    <ul class="outside">
      <li>Check the soil before watering. Wipe up water spilled outside the pot so that other visitors do not slip.</li>
      <li>Read the labels and signs, then follow the path. Compare how the second line of a wrapped list item aligns with its first line.</li>
    </ul>
    <h2>inside list</h2>
    <ul class="inside">
      <li>Check the soil before watering. Wipe up water spilled outside the pot so that other visitors do not slip.</li>
      <li>Read the labels and signs, then follow the path. Compare how the second line of a wrapped list item aligns with its first line.</li>
    </ul>
    <h2>Preparation in order</h2>
    <ol><li>Read the notice.</li><li>Prepare a watering can.</li><li>Put tools back after use.</li></ol>
  </main>
</body>
</html>

测试每个间距更改

  1. 将窗口宽度缩小,使列表项跨越多于一行。对 outside 列表,检查后续行是否与第一行正文的起点对齐;对 inside 列表,检查第二行是否延伸到标记下方的区域。
  2. 将 .intro 的 text-indent 值改为 0,检查是否只有第一段首行的起点改变,然后恢复为 1.5em。
  3. 将段落的 margin-block-end 值更改为 0。确保在保持段落内行间距的情况下减少段落之间的空白。先把段落末端外边距恢复为 1.2em,再单独将 line-height 从 1.65 改为 1.2,比较后恢复为 1.65。
  4. 通过将 li + li 的 0.45em 改为 0 和 1em 来比较。确认项目内部的行距与第一项前的间距不因这条规则改变,比较后恢复为 0.45em。

如果一个符号被截断,请检查列表的内边距和外部元素的溢出。如果只有某些段落的间距不同,请检查选择器和浏览器默认样式。整个示例中的 65ch 是基于数字 0 的宽度的最大长度,并不是字符数量的固定值。