Chapter 03 / 10

列表与任务列表

无序/有序列表的规则细节、嵌套缩进原理、GFM 任务列表与常见排版误区

无序列表(Unordered Lists)

无序列表由列表标记符 + 空格 + 内容组成。Markdown 支持三种列表标记符:-(连字符)、*(星号)、+(加号)。

三种写法(结果相同)
# 连字符(推荐)
- 苹果
- 香蕉
- 橙子

# 星号
* 苹果
* 香蕉

# 加号
+ 苹果
+ 香蕉
渲染效果
  • 苹果
  • 香蕉
  • 橙子
INFO(一致性原则)同一个列表内应该使用同一种标记符。如果同一列表中混用 -*,某些解析器可能将其解析为两个独立的列表,而不是一个列表。GFM 规范规定同一种标记符才属于同一列表。

列表标记符与内容之间的空格数

标记符和内容之间需要至少 1 个空格(CommonMark 允许 1-4 个空格)。第一个内容字符的位置决定了列表项的"内容起始列",这对嵌套和多段落列表很重要:

# 1个空格(最常见)
- 内容从这里开始

# 4个空格(对齐时用)
-   内容从这里开始(列表标记后4个空格)

有序列表(Ordered Lists)

有序列表用数字 + 点号(.)或右括号())+ 空格开头:

源码
# 常规写法(推荐)
1. 第一步:下载安装包
2. 第二步:运行安装程序
3. 第三步:配置环境变量

# 全用 1.(数字会自动递增)
1. 第一步
1. 第二步
1. 第三步

# 数字可以不从1开始
3. 从3开始
1. 下一个
8. 再下一个
渲染效果
  1. 第一步:下载安装包
  2. 第二步:运行安装程序
  3. 第三步:配置环境变量

↑ 全用1.写法效果完全相同

  1. 从3开始
  2. 下一个
  3. 再下一个
列表起始数字
CommonMark 规范规定,有序列表的第一个数字决定列表的起始编号(生成 HTML start 属性),但后续的数字完全被忽略,渲染器自动递增。所以 3. 1. 8. 会渲染为 3、4、5。
点号 vs 括号
数字后面可以用 .(点号)或 )(右括号)。1.1) 效果相同,但 GFM 规范中,两种标记符混用会被视为不同列表。实践中统一使用 . 即可。

有序列表 vs 无序列表的选择

选用有序列表(1. 2. 3.)选用无序列表(- - -)
步骤有明确先后顺序(安装、部署步骤)项目之间没有顺序关系(功能特性、工具列表)
有排名或优先级(Top 3 原因)并列选项(支持的操作系统)
需要引用特定步骤("见步骤 3")枚举集合(可用命令列表)

嵌套列表(Nested Lists)

通过缩进创建子列表。子列表项需要缩进到与父列表项内容起始列对齐的位置,或更深:

源码(推荐缩进2或4空格)
- 前端技术栈
  - HTML/CSS
  - JavaScript
    - React
    - Vue
  - TypeScript
- 后端技术栈
  - Python(Flask / FastAPI)
  - Go(Gin / Echo)
渲染效果
  • 前端技术栈
    • HTML/CSS
    • JavaScript
      • React
      • Vue
    • TypeScript
  • 后端技术栈
    • Python(Flask / FastAPI)
    • Go(Gin / Echo)

嵌套列表的缩进规则详解

CommonMark 对嵌套缩进有精确规定,这是 Markdown 中最容易出错的地方之一:

内容起始列(Content Column)
列表项的内容(第一个非空字符)所在的列号。对于 - 内容,内容从第3列开始(- 占第1列,空格占第2列,内容从第3列开始)。子列表项必须缩进到至少这一列。
实际建议
为了最大兼容性和一致性,推荐统一使用 2个空格4个空格缩进每一级。不同项目可选择不同标准,但同一文件内保持一致。
# 规范用法(2空格缩进)
- 父项
  - 子项(2空格)
    - 孙项(4空格)

# 规范用法(4空格缩进)
- 父项
    - 子项(4空格)
        - 孙项(8空格)

# 容易出错的写法(3空格,部分解析器行为不一致)
- 父项
   - 子项(3空格)
WARNING(Tab vs 空格)不要使用 Tab 键缩进列表,因为 Tab 的宽度在不同编辑器中不同(通常是 2、4 或 8 个空格),会导致在不同环境中渲染结果不同。始终使用空格缩进 Markdown 列表。

列表中的多段落(Loose Lists)

有时需要在一个列表项中包含多个段落,这涉及到 "宽松列表"(Loose List)和"紧凑列表"(Tight List)的概念:

紧凑列表(Tight List)
列表项之间没有空行,各列表项被渲染为紧密排列的文字(不加 <p> 标签包裹)。这是最常见的列表形式。
宽松列表(Loose List)
列表项之间有空行,各列表项被渲染为段落形式(加 <p> 标签包裹)。看起来列表项之间间距更大。
紧凑列表(项间无空行)
- 第一项
- 第二项
- 第三项
宽松列表(项间有空行)
- 第一项

- 第二项

- 第三项

在列表项中加入多段落

一个列表项可以包含多个段落,第二段及之后的段落需要缩进到内容起始列:

1. 第一步:安装依赖

   运行以下命令安装所有必要的依赖包:
   (注意:这段文字缩进了 3 个空格,与"第"字对齐)

   ```bash
   npm install
   ```

2. 第二步:配置环境

   复制 `.env.example` 文件并修改配置。
  1. 第一步:安装依赖

    运行以下命令安装所有必要的依赖包:

  2. 第二步:配置环境

    复制 .env.example 文件并修改配置。

INFO列表项内的续接内容(段落、代码块、引用块)都需要缩进到该列表项内容的起始列。对于 1. 开头的有序列表,内容从第4列开始,续接内容需要缩进 3 个空格(有时用4个更方便记忆)。

GFM 任务列表(Task Lists)

GitHub Flavored Markdown 扩展语法,在无序列表标记后加 [ ](未完成)或 [x](已完成)创建复选框:

源码
## 发布前检查清单

- [x] 编写单元测试
- [x] 通过 CI/CD 流水线
- [x] 代码审查(Code Review)
- [ ] 更新 CHANGELOG
- [ ] 更新版本号
- [ ] 发布到 npm
- [ ] 发送发布通知
渲染效果

发布前检查清单

  • 编写单元测试
  • 通过 CI/CD 流水线
  • 代码审查(Code Review)
  • 更新 CHANGELOG
  • 更新版本号
  • 发布到 npm
  • 发送发布通知

任务列表的实用场景

GitHub Issues

  • 在 Issue 正文中创建任务列表
  • 完成进度显示在 Issue 列表(如"3/7 tasks")
  • 可直接点击复选框切换状态

Pull Request 描述

  • 列出 PR 包含的变更项
  • 列出 reviewers 需要验证的内容
  • 作为 PR 合并前的检查清单

项目 README

  • 显示功能实现进度(Roadmap)
  • 展示已完成和计划中的特性

个人笔记(Obsidian/Notion)

  • 每日待办事项
  • 项目里程碑跟踪
  • 学习计划
TIP任务列表是 GFM 扩展,在 CommonMark 解析器中不会渲染为复选框,而是显示为普通列表([ ][x] 会作为字面量显示)。如果你的目标平台不支持 GFM,需要用其他方式表示任务状态(如用 ✅ ❌ 表情符号)。

任务列表中嵌套子任务

任务列表可以嵌套,表示主任务和子任务:

- [ ] 完成用户认证模块
  - [x] 设计数据库 Schema
  - [x] 实现注册 API
  - [ ] 实现登录 API
  - [ ] 实现 JWT 刷新
- [x] 完成商品列表页
- [ ] 完成购物车功能

列表与代码块、引用的结合

列表项中包含代码块

列表项内的代码块需要缩进到内容起始列:

1. 安装 Node.js:

   ```bash
   # 使用 nvm 安装
   nvm install 20
   nvm use 20
   ```

2. 验证安装:

   ```bash
   node --version  # 应输出 v20.x.x
   npm --version
   ```

列表项中包含引用块

- 关于这个决策,官方文档写道:

  > The simplest solutions are often the best.
  > — Occam's Razor

- 另一条原则...

混合有序与无序列表

可以将有序列表和无序列表混合嵌套,但要注意缩进一致性:

源码
1. 准备材料
   - 高筋面粉 200g
   - 鸡蛋 2个
   - 牛奶 100ml
2. 混合搅拌
   - 将干料混合
   - 加入湿料
3. 煎制 5-8 分钟
渲染效果
  1. 准备材料
    • 高筋面粉 200g
    • 鸡蛋 2个
    • 牛奶 100ml
  2. 混合搅拌
    • 将干料混合
    • 加入湿料
  3. 煎制 5-8 分钟

定义列表(扩展语法)

某些 Markdown 扩展(Pandoc、PHP Markdown Extra、kramdown)支持定义列表,适合术语表和词汇表:

Markdown
:   一种轻量级标记语言,使用简单符号描述文档结构。

CommonMark
:   精确的 Markdown 规范,解决了原始规范的歧义问题。
:   官网:commonmark.org

GFM(GitHub Flavored Markdown)
:   GitHub 基于 CommonMark 的扩展版本,增加了表格、任务列表等特性。
WARNING定义列表语法不属于 CommonMark 和 GFM 规范,GitHub 不会渲染,只会显示原始文字。如果目标平台是 GitHub,需要改用其他方式(如用 <dl>/<dt>/<dd> HTML 标签,或用表格替代)。

列表排版的最佳实践

内容格式一致性

# ❌ 不好:格式不一致
- 使用 Python 3.10+
- 安装 pip 依赖(requirements.txt)
- 配置好环境变量(重要!)。

# ✅ 好:格式一致(都是命令式动词,都不加句号)
- 安装 Python 3.10+
- 安装 pip 依赖(见 requirements.txt)
- 配置环境变量(见 .env.example)

列表项长度

标记符的选择

# 项目规范推荐
- 统一使用 `-` 作为无序列表标记符(与 GFM 风格一致)
- 统一使用 `1.` 作为有序列表标记符
- 同一列表内不混用不同标记符
- 嵌套缩进使用 2 个空格(与 YAML 缩进保持一致,避免混乱)

小结

本章要点