Markdown 列表语法
无序/有序/任务列表语法、嵌套缩进规则、起始序号控制与列表内嵌块级元素的细节。
认知导入(Layer 0 生存层) 前置知识:003 段落与换行。 边界说明:列表是”并列信息”的默认表达。本篇的核心难点只有一个——缩进决定层级;其余都是三种列表的排列组合。 强制练习:分别用
-和1.写三行列表;把第二行缩进两个空格,观察它如何变成子项。
1. 无序列表
1.1 语法
-、*、+ 加一个空格开头,三种标记渲染效果完全一致。团队内统一用一种(推荐 -,输入最快且不会被斜体语法干扰):
- 无序列表项 1
- 无序列表项 2
- 无序列表项 3
标记后必须有空格:-列表项 不是列表,是普通文本。
1.2 多行内容与续行
列表项内容太长需要换行时,续行缩进到与首行文本对齐(懒延续也允许不缩进,但对齐写法更可靠、更易读):
- 这是一个很长的列表项,
换行后与首行文本对齐,
仍然属于同一个列表项
- 另一个列表项
1.3 松散与紧凑
项与项之间加空行会形成”松散列表”,渲染时行距更大(每项包裹在段落里);不加空行则是紧凑列表。两种都合法,同一文档保持一种风格(详见 markdown/070-BlockquoteNestedList)。
2. 有序列表
2.1 语法
数字 + 英文句号 + 空格 开头:
1. 第一项
2. 第二项
3. 第三项
2.2 序号规则:首项决定起始值
这是有序列表最容易被讲错的规则,分两层:
- 第一项的数字决定列表从几开始:写
3. a\n4. b会渲染成从 3 开始的列表(用于在长文档中续接编号); - 后续项的数字不影响显示:全部写
1.也能渲染出递增序号,渲染序号自动连续。
3. 从三开始
4. 自动递增为四
5. 自动递增为五
实践建议:源码按真实顺序书写(1. 2. 3.),既保证起始值正确,也让 diff 与阅读友好。
2.3 有序列表也能嵌套
子项缩进到父项内容列(1. 占 3 列,缩进 3 空格):
1. 一级项
1. 二级项
2. 二级项
2. 另一个一级项
3. 任务列表
任务列表是 GFM 扩展:在列表项开头加 [ ](未完成)或 [x](已完成,大小写均可):
- [ ] 未完成的待办任务
- [x] 已完成的待办任务
- [ ] 可嵌套的子任务
识别条件严格:标记必须是列表项内容的开头、方括号内只能有空格或 x、标记后必须有空格。GitHub/GitLab 上复选框可点击勾选并写回源码。详细语义、交互行为与渲染器差异见 markdown/170-TaskList。
4. 嵌套列表与缩进规则(本篇重点)
4.1 缩进的本质:对齐父项内容列
CommonMark 的判定标准是”子列表缩进到父项内容的起始列”,不是全局固定值:
- 无序父项
- 二级项(缩进 2 空格,对齐"无"字)
- 三级项(再缩进 2 空格)
1. 有序父项
- 二级项(缩进 3 空格,对齐"有"字)
10. 两位数父项
- 二级项(缩进 4 空格)
两条硬性边界:
- 缩进不足(少于父项内容列):子项被解析为父项的同级,层级塌掉——这是嵌套列表翻车的第一名;
- 缩进过头(相对内容列达到 4 空格):内容被解析为缩进式代码块,出现奇怪的缩进代码。
因此”嵌套列表必须缩进 4 空格”是一个流传很广的误解:对 - 项它反而逼近代码块阈值,正确做法是最小对齐缩进(无序 2 空格、有序 3 空格)。
4.2 制表符风险
CommonMark 把制表符按”跳到下一个 4 列倍数”展开,理论上一个制表符等价 4 空格;但不同编辑器对 Tab 的显示宽度不同,混用空格与制表符是层级错乱的常见根源。列表缩进只用空格,并在编辑器里开启”Tab 转空格”。
4.3 不同类型混合嵌套
无序与有序可以互相嵌套:
- 无序列表项
1. 内部有序第一步
2. 内部有序第二步
- 无序列表项
4.4 层级深度建议
渲染层面没有硬性上限,但三层以上读者就难以追踪归属,超过三层应考虑拆分列表或改用小标题。
5. 列表项内嵌块级元素
列表项可以承载段落、代码块、引用等块级元素,关键是整体缩进到父项内容列。
5.1 嵌入代码块(推荐围栏式)
- 列表项 1
```python
print("Hello, World!")
```
- 列表项 2
代码块缩进 2 空格(与 - 项的内容列对齐)即可识别为项内代码块;缩进式代码块则要求相对内容列再加 4 空格,容易出错,优先用围栏式。
5.2 嵌入引用
- 列表项 1
> 这是列表项内的引用
> 可以跨多行
- 列表项 2
5.3 嵌入链接与图片
行内元素直接写即可:
- [Markdown 指南](https://www.markdownguide.org)
- 本地图片:
图片路径建议使用仓库内相对路径而非外部占位图服务(外链图床容易失效)。
5.4 嵌入段落
空行 + 缩进:
- 列表项 1
这是列表项内的一个段落,可以写详细说明。
- 列表项 2
6. 列表与段落的边界行为
CommonMark 规定:列表可以打断段落(无序列表、以及首项为 1 的有序列表可以直接跟在段落文字后一行开始);首项不是 1 的有序列表不能打断段落。这在”正文后直接写列表”时通常无害,但当你写的是以连字符开头的一行普通文字(如日期 - 2026-01-01 事件)时,可能意外变成列表——必要时用转义 \- 或前置空行处理。
7. 常见问题排查
| 现象 | 原因 | 解决 |
|---|---|---|
| 列表显示为普通文本 | 标记后缺空格 | - 列表项(减号后加空格) |
| 嵌套项与父项同级 | 缩进少于内容列 | 无序 2 空格、有序 3 空格 |
| 子项变成代码块 | 缩进达到内容列 +4 空格 | 减少缩进到对齐即可 |
| 有序列表从 2 或 3 开始 | 首项数字不是 1 | 起始序号由首项数字决定 |
| 任务没有复选框 | 渲染器不支持 GFM 或标记写法错误 | 核对 [ ] 与空格;换 GFM 渲染器 |
| 列表项间距忽大忽小 | 紧凑/松散混用 | 项间统一不加空行 |
小结
- 初学者要点:无序用
-、有序用1.,标记后加空格;嵌套缩进”无序 2 空格、有序 3 空格”;列表里放代码块用围栏式并保持缩进。 - 进阶注意:缩进的本质是对齐父项内容列,4 空格是代码块阈值不是列表标准;有序列表的起始值由首项数字决定、后续数字被忽略;任务列表是 GFM 扩展(详见
markdown/170-TaskList);列表可打断段落,首项非 1 的有序列表除外;缩进只用空格不用制表符。