Markdown 任务列表语法完全指南

Markdown 任务列表是什么

写项目文档或者做笔记的时候,经常需要列一个待办清单——哪些事做了、哪些还没做。Markdown 的任务列表(task list)就是干这个的,它能在列表项前面加一个可勾选的复选框,让你一眼看清进度。

这种语法最早是 GitHub 在 2013 年引入的,属于 GitHub Flavored Markdown(GFM)扩展语法,并不在原始 Markdown 规范里。后来被大多数主流 Markdown 编辑器和平台采纳,现在用起来已经很普遍了。不过 CommonMark 论坛讨论过是否把任务列表纳入标准,结论是它"会一直作为扩展存在"——主要原因是任务列表的实用性很大程度上依赖交互式切换功能,这已经超出了纯文本到 HTML 转换的范畴。

这篇文章会把语法规则、嵌套写法、常见坑、以及不同平台的兼容性都讲清楚。不管你是用 GitHub 写 README,还是在 Obsidian 做笔记管理,看完应该都能上手。

基本语法:怎么写一个任务列表

未完成的任务

在无序列表项的基础上,把内容前面的 [ ](左方括号 + 空格 + 右方括号)加上就行:

- [ ] 写项目文档
- [ ] 提交代码审查
- [ ] 部署到测试环境

渲染效果:

  • [ ] 写项目文档
  • [ ] 提交代码审查
  • [ ] 部署到测试环境

已完成的任务

把方括号里的空格换成小写 x,就变成勾选状态:

- [x] 搭建开发环境
- [x] 完成需求分析
- [ ] 编写单元测试

渲染效果:

  • [x] 搭建开发环境
  • [x] 完成需求分析
  • [ ] 编写单元测试

大写 X 也能用,效果一样:- [X] 搞定了。大部分渲染器对 xX 一视同仁,但我自己的习惯是统一用小写,看着整齐一些。

语法要点:每个空格都有意义

说实话,这个语法虽然看着简单,但空格的位置卡得挺严。我之前踩过一个坑,少打了一个空格,复选框死活不显示。正确的格式是这样的:

列表标记(- 或 * 或 +)+ 空格 + [ + 空格 + ] + 空格 + 文本内容

用图示拆解一下:

- [ ] 任务内容
↑ ↑ ↑ ↑
│ │ │ └── 右方括号
│ │ └──── 方括号内必须是空格(未完成)或 x/X(已完成)
│ └────── 左方括号
└──────── 列表标记,后面跟一个空格

几个容易出错的地方:

  • - [ ] 的第一个空格(列表标记和 [ 之间)不能少
  • [ ] 里面必须是一个空格,不能是两个,也不能没有
  • ] 和文字之间也必须有一个空格
✅ - [ ] 正确写法
❌ -[] 缺少空格,不会渲染成复选框
❌ - [  ] 多了一个空格,可能不会渲染
❌ - []没有空格,方括号会变成普通文字

我之前有一次写 README, - [] 后面的空格漏了,结果方括号直接显示成了文本,排查了好一会儿才发现。

用其他列表标记

- 不是唯一的选择。*+ 也都能用:

* [ ] 用星号开头
+ [ ] 用加号开头
- [ ] 用减号开头

这三种写法在 GitHub、GitLab 和大多数编辑器里效果相同。不过有一点要注意:如果你习惯在同一个文档里混用这几种符号,最好别在同一个任务列表里混,部分解析器会把它们识别成不同的列表块。

另外,任务列表不限于无序列表。在有序列表里也能写,虽然用得不多:

1. [ ] 第一步
2. [x] 第二步
3. [ ] 第三步

这个写法在 GitHub 上是支持的,不过在有些编辑器里可能只显示数字,不显示复选框。

嵌套任务列表

任务列表支持嵌套,这对于拆分子任务特别有用。缩进规则和普通列表嵌套一样——子项缩进 2 到 4 个空格(或者一个 Tab):

- [ ] 项目上线
  - [x] 购买域名
  - [x] 配置服务器
  - [ ] 性能测试
    - [x] 首页加载速度
    - [ ] 接口压力测试
  - [ ] 正式发布

渲染效果:

  • [ ] 项目上线
    • [x] 购买域名
    • [x] 配置服务器
    • [ ] 性能测试
    • [x] 首页加载速度
    • [ ] 接口压力测试
    • [ ] 正式发布

嵌套可以多层叠加,不过建议别超过 3 层,否则可读性会变差。对了,缩进的时候用空格还是 Tab 都行,但同一个列表里不要混用,混了可能导致层级解析混乱。

任务列表里加其他格式

任务列表项的内容和普通文本一样,可以包含加粗斜体链接代码 等 Markdown 格式:

- [x] 阅读 [Markdown 官方文档](https://www.markdownguide.org)
- [ ] 给 `parse()` 函数添加**错误处理**
- [ ] 写一篇关于 *GitHub Flavored Markdown* 的教程

在 GitHub 上,你甚至可以在任务列表里引用 issue 或者 PR:

- [ ] 修复登录页 bug #123
- [x] 合并 PR #456
- [ ] 参考 https://github.com/org/repo/issues/789

这样写的话,GitHub 会自动展开这些引用,显示 issue 的标题和状态,非常方便做项目管理。

在表格里显示复选框

这是一个很多人会遇到的问题——任务列表的 - [ ] 语法在表格里不生效,方括号会直接显示为文本。因为表格的单元格是内联解析的,不支持列表语法。

之前有一次做项目进度表,我想在表格里加复选框,试了各种方法。最后发现几种替代方案:

方案一:HTML 实体

用 Unicode 字符直接显示勾选框:

| 功能 | 状态 |
|------|------|
| 用户登录 | ☑ |
| 数据导出 | ☐ |
| 权限管理 | ☐ |

☑ 是 ☑(已勾选),☐ 是 ☐(未勾选)。

方案二:Emoji

用 emoji 字符或快捷码(GitHub 支持):

| 功能 | 状态 |
|------|------|
| 用户登录 | :white_check_mark: |
| 数据导出 | :white_large_square: |

方案三:HTML checkbox

直接用 HTML 标签,在支持 HTML 的渲染器里有效:

| 功能 | 状态 |
|------|------|
| 用户登录 | <input type="checkbox" checked disabled> |
| 数据导出 | <input type="checkbox" disabled> |

这三种方案各有适用场景。HTML 实体兼容性最好,emoji 在 GitHub 上效果不错,HTML 标签则在支持 HTML 嵌入的编辑器里表现最好。但要注意,这三种方法显示的都是静态图标,不能像普通任务列表那样点击切换。

常见问题和故障排除

复选框不显示

这是最常见的坑。排查顺序:

  1. 检查空格- [ ] 每个位置都有空格吗?最容易漏的是 ] 后面那个
  2. 检查渲染器:你用的编辑器或平台支持 GFM 任务列表吗?(见下一节兼容性表格)
  3. 检查缩进:如果是嵌套任务列表,缩进是否对齐?Tab 和空格有没有混用?
  4. 检查列表标记:前面有没有写 -*+?直接写 [ ] 是不行的

勾选后不能点击切换

任务列表有两种模式:

  • 交互式:可以点击复选框切换状态(GitHub Issues/PR、Obsidian、一些编辑器)
  • 静态展示:只显示复选框但不能点击(GitHub README 文件、普通 Markdown 预览)

在 GitHub 上,Issues 和 Pull Request 里的任务列表是可以点击切换的,但 README.md 文件里的任务列表是只读的——要修改状态得编辑源文件,把 [ ] 改成 [x]

GitHub 上 tasklist blocks 已退役

GitHub 之前支持一种更高级的 tasklist blocks 语法(用 ``tasklist 代码块),可以引用其他 issue 作为子任务。这个功能在 2024 年已经退役了,现在推荐使用 GitHub 的 sub-issues 功能替代。普通的- [ ]` 任务列表语法不受影响,继续正常使用就行。

多平台兼容性对比

不同环境对任务列表的支持程度差异不小。我实际测试了几个常用平台,整理了下面这张表:

平台/编辑器渲染复选框交互式切换备注
GitHub Issues/PR/Comments支持最完整,可拖拽排序
GitHub README/Wiki只读展示,需编辑源文件修改状态
GitLab和 GitHub 类似
VS Code 内置预览⚠️部分版本不渲染复选框,显示为列表项
Typora直接点击复选框切换
Obsidian原生支持,可配合插件增强
Jupyter Notebook不支持,显示为普通列表
Pandoc⚠️需要特定扩展才能渲染
CSDN支持渲染,但交互性取决于编辑模式
印象笔记 Markdown内置支持,快捷键 Ctrl+Shift+C

说实话,这个兼容性问题还挺让人头疼的。我的建议是:如果你写的内容要在多个平台发布,先确认目标平台是否支持,不行的话提前想好替代方案。

实际应用场景

项目 README 待办清单

在项目根目录的 README 里放一个任务列表,记录待完成的功能或已知问题:

## 开发计划

- [x] 用户注册/登录
- [x] 文章 CRUD
- [ ] 评论系统
- [ ] 搜索功能
- [ ] 移动端适配

会议纪要

把会议讨论的行动项用任务列表记录,会后分发给相关同学追踪:

## 2024-01-15 产品周会

- [x] @张三 确认需求文档终版
- [ ] @李四 完成技术方案评审
- [ ] @王五 输出测试用例
- [ ] 全组 本周五前完成代码走查

发布清单

每次发版前对着列表逐项确认,不容易遗漏:

## v2.0 发布清单

- [x] 所有单元测试通过
- [x] 代码合并到 main 分支
- [ ] 生产环境数据库迁移
- [ ] 更新版本号
- [ ] 生成 changelog
- [ ] 通知运维团队

个人笔记管理

在 Obsidian 或者其他支持任务列表的笔记工具里,用任务列表做日常计划或者学习追踪:

## 本周学习计划

- [x] 完成 Rust 第五章练习
- [ ] 读完《Designing Data-Intensive Applications》第 7 章
- [ ] 整理 WebAssembly 学习笔记
- [ ] 写一篇 Markdown 任务列表教程 😄

和相关语法的区别

如果你之前看过 Markdown 列表 的教程,可能会问:任务列表和普通列表有什么区别?

简单来说:

特性普通列表任务列表
语法- 内容- [ ] 内容
复选框
交互性部分平台支持点击切换
用途列举要点追踪完成状态
规范归属核心 MarkdownGFM 扩展

还有一个容易混淆的概念是 Markdown 复选框——其实它和任务列表是同一种语法,只是叫法不同。任务列表(task list)、复选框列表(checkbox list)、待办清单(todo list / checklist)指的都是这个 - [ ] 语法。

参考来源

  1. GitHub Docs - About Tasklists
  2. Markdown Guide - Extended Syntax: Task Lists
  3. GitHub Blog - Task Lists in All Markdown Documents
  4. CommonMark Forum - Task Lists in Standard Markdown
  5. Stack Overflow - How to draw checkbox in GitHub Markdown table