你是不是也有过这样的经历:在写 Markdown 文档、博客或者 README 的时候,明明心里想着要弄个清晰的层级结构,结果写出来的列表要么缩进乱七八糟,要么编号对不上,甚至有时候 <li> 标签套得让人怀疑人生。
别急,今天我们就把这些“排版黑洞”彻底打通。咱们不聊虚的,直接拿真实项目中的常见场景来说事,保证你看完就能上手。
为什么嵌套列表总是“炸”?
首先,咱们得搞清楚,为什么列表会乱?核心原因通常有两个:
- 缩进不一致:Markdown 对缩进非常敏感,尤其是嵌套层数多的时候。
- 混合使用无序和有序:无序列表里套有序,或者反过来,很容易搞混符号和编号的逻辑。
举个真实的例子。假设你在写一个 Git 分支管理指南,里面包含:
- 创建分支
- 步骤一:查看当前分支
- 步骤二:创建新分支
- 推荐使用
git checkout -b feature/xxx
- 推荐使用
- 步骤三:切换到新分支
如果你用纯 Markdown 写,很容易写成这样:
- 创建分支
1. 步骤一:查看当前分支
2. 步骤二:创建新分支
- 推荐使用 `git checkout -b feature/xxx`
3. 步骤三:切换到新分支
表面上看好像没问题,但有些 Markdown 渲染器(比如 GitHub 的某些旧版本,或者 Obsidian 的某些主题)会因为缩进层级不清晰而渲染异常。比如,第 2 步下面的无序列表项可能不会正确缩进,或者编号会错位。
真实项目案例:API 文档中的嵌套列表
假设你在写一个 REST API 文档,请求参数部分需要嵌套列表。比如,创建一个“用户”对象,需要传递以下参数:
name:用户名,必填email:邮箱,必填settings:用户设置,可选theme:主题,可选,默认是“light”notifications:通知设置,可选email:是否开启邮件通知,默认是truesms:是否开启短信通知,默认是false
如果直接用 Markdown 写,很容易写成:
- `name`:用户名,必填
- `email`:邮箱,必填
- `settings`:用户设置,可选
- `theme`:主题,可选,默认是“light”
- `notifications`:通知设置,可选
- `email`:是否开启邮件通知,默认是 `true`
- `sms`:是否开启短信通知,默认是 `false`
这个例子其实已经比较清晰了,但如果你再加一层嵌套,比如 notifications 下面还有更详细的配置,就会开始乱。比如:
- `name`:用户名,必填
- `email`:邮箱,必填
- `settings`:用户设置,可选
- `theme`:主题,可选,默认是“light”
- `notifications`:通知设置,可选
- `email`:是否开启邮件通知,默认是 `true`
- `frequency`:邮件频率,可选,默认是“daily”
- `sms`:是否开启短信通知,默认是 `false`
这时候,你可能发现 frequency 这一项的缩进有点别扭,渲染出来可能不会正确嵌套在 email 下面。
解决方案:统一缩进,明确层级
1. 使用 2 个空格作为一级缩进
这是 Markdown 的黄金法则。无论嵌套多深,每一层都用 2 个空格(或 1 个 Tab)作为缩进。比如上面的 API 文档例子,可以写成:
- `name`:用户名,必填
- `email`:邮箱,必填
- `settings`:用户设置,可选
- `theme`:主题,可选,默认是“light”
- `notifications`:通知设置,可选
- `email`:是否开启邮件通知,默认是 `true`
- `frequency`:邮件频率,可选,默认是“daily”
- `sms`:是否开启短信通知,默认是 `false`
这样写,每一层的缩进都是 2 的倍数,渲染器会更容易识别层级关系。
2. 避免在有序列表中使用无序列表嵌套
如果你需要在有序列表里嵌套无序列表,最好把有序列表和无序列表分开写。比如:
1. 创建分支
2. 切换分支
3. 提交代码
以下是提交代码的注意事项:
- 确保代码已通过测试
- 提交信息要清晰
这样写,逻辑更清晰,不会让读者混淆。
3. 使用 HTML 辅助复杂嵌套
如果 Markdown 实在搞不定,可以借用 HTML 的 <ul> 和 <ol> 标签。比如:
<ul>
<li>创建分支</li>
<li>切换分支</li>
<li>提交代码
<ul>
<li>确保代码已通过测试</li>
<li>提交信息要清晰</li>
</ul>
</li>
</ul>
这样写,层级关系一目了然,而且兼容性更好。
代码示例:如何用 Python 生成规范的嵌套列表
假设你正在写一个自动化工具,需要生成规范的嵌套列表文档。你可以用 Python 来帮你生成。比如:
def generate_nested_list(data, indent=0):
prefix = " " * indent
for key, value in data.items():
if isinstance(value, dict):
print(f"{prefix}- {key}:")
generate_nested_list(value, indent + 1)
else:
print(f"{prefix}- {key}: {value}")
# 示例数据
api_params = {
"name": "用户名,必填",
"email": "邮箱,必填",
"settings": {
"theme": "主题,可选,默认是'light'",
"notifications": {
"email": {
"is_enabled": "是否开启邮件通知,默认是 True",
"frequency": "邮件频率,可选,默认是'daily'"
},
"sms": {
"is_enabled": "是否开启短信通知,默认是 False"
}
}
}
}
generate_nested_list(api_params)
运行这段代码,你会得到:
- name: 用户名,必填
- email: 邮箱,必填
- settings:
- theme: 主题,可选,默认是'light'
- notifications:
- email:
- is_enabled: 是否开启邮件通知,默认是 True
- frequency: 邮件频率,可选,默认是'daily'
- sms:
- is_enabled: 是否开启短信通知,默认是 False
这样生成的列表,层级清晰,缩进规范,直接复制到 Markdown 文档里就可以了。
小结:告别排版混乱的 3 个关键
- 统一缩进:每一层用 2 个空格(或 1 个 Tab)缩进,别混用。
- 避免混合嵌套:有序和无序列表尽量分开,别搞得太复杂。
- 用工具辅助:写复杂嵌套列表时,用代码生成,避免手动出错。
下次再遇到嵌套列表排版问题,记得这三招,保证你写得清清楚楚,读者看得明明白白。
