嵌套列表

嵌套列表让一份清单能表达层级:功能点下面挂子功能,步骤里面再分步骤,配置项下面列具体字段。但 Markdown 里没有专门的「嵌套」语法——层级完全靠缩进表达,于是「缩进多少」就成了一个必须精确回答的问题。坊间流传着「二级列表必须缩进四个空格」的说法,这其实是把某一种写法当成了规范。这一页要给出真正起作用的规则,并说明为什么两格和四格都能work。

语法

子项只要缩进到父项内容起始的那一列或更右,就会被认作它的子项:

- 一级
  - 二级
    - 三级
- 另一项
<ul>
<li>一级
<ul>
<li>二级
<ul>
<li>三级</li>
</ul>
</li>
</ul>
</li>
<li>另一项</li>
</ul>

真正的规则:内容起始列

缩进多少合适,取决于父项的内容起始列,也就是标记符号本身占掉的宽度:

父项标记标记占宽子项应缩进
- 加空格2 列2 列
* 加空格2 列2 列
+ 加空格2 列2 列
1. 加空格3 列3 列
10. 加空格4 列4 列

所以短横线列表缩进两格就对,有序列表的子项要缩进三格。而缩进四格在短横线列表里同样有效——因为四格仍然落在「父项内容列到内容列加四格」这个区间内,解析器会把它当成子列表而不是代码块。真正会变的是再往右一格:短横线列表的子项缩进到六格时,就越过代码块的门槛了。

换句话说,两格和四格都行,关键是别超过上限。

一致性比具体数值更重要

同一个层级的兄弟项,缩进必须落在同一档里。缩进不一致时,解析器可能把它们拆成两个平级的子列表,视觉上像是多了一层:

- 一级
    - 四格的二级
  - 两格的二级
<ul>
<li>一级
<ul>
<li>四格的二级</li>
<li>两格的二级</li>
</ul>
</li>
</ul>

上面这个例子因为两格和四格都还在同一个区间内,所以侥幸被合成一个子列表。但只要有一项越过了门槛,它就会被甩出去,变成代码块或者另起一个列表。

常见坑

写法实际渲染原因
子项缩进两格正常嵌套短横线的内容起始列是第 3 列
子项缩进四格正常嵌套仍在子列表区间内
子项缩进六格变成代码块超过内容起始列四格
兄弟项缩进不一致可能被拆成两个列表同一层级要落在同一档
子项换了符号另起一个子列表换符号等于另起一个列表

练习

把下面这段内容改写成 Markdown 要求:三个顶层要点用一个无序列表表示;「安装依赖」下面挂两个子项;「配置」下面挂一个有序子列表,子列表的第一个编号必须是 1。整份文档的缩进保持一致。

安装依赖
  安装 pnpm
  执行 pnpm install
配置
  环境变量
    列出 NODE_ENV
    列出 PORT
发布
缩进一致性

解题思路: 嵌套靠缩进表达,缩进量取决于父项的内容起始列。短横线 - 占两列,所以无序列表的子项缩进两个空格;有序列表 1. 占三列,所以它的子项缩进三个空格。整份文档统一用空格,不用制表符。

详细步骤:

  1. 三个顶层要点各写 - 加空格,顶格排列。
  2. 「安装 pnpm」和「执行 pnpm install」是「安装依赖」的子项,缩进两个空格再写 - ,与父项的内容起始列对齐。
  3. 「环境变量」是「配置」的子项,同样缩进两个空格;但它下面还要再挂一层有序列表。
  4. 「列出 NODE_ENV」和「列出 PORT」构成一个有序列表,它挂在「环境变量」下面。「环境变量」这一行前面有两个空格,它的内容从第 5 列开始,所以这个有序列表整体要缩进四个空格;列表内部的编号写 1. 和 2.。
  5. 检验:渲染后是三个顶层要点,「安装依赖」下有两个子项,「配置」下有一个有序子列表。

最终答案:

- 安装依赖
  - 安装 `pnpm`
  - 执行 `pnpm install`
- 配置
  - 环境变量
    1. 列出 `NODE_ENV`
    2. 列出 `PORT`
- 发布

小结

读完这一页,你应当能说出嵌套靠缩进表达、而缩进量由父项的内容起始列决定,能说清两格和四格为什么都有效、什么情况下会变成代码块,也能在「层级莫名多了一层」时想到是兄弟项缩进不一致。接下来写多层清单时,你会先确定顶层用哪种标记,再按标记占宽统一每一层的缩进,而不是随手敲空格。

发现内容有问题?

告诉我们哪里需要改进。