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] 首頁載入速度
    - [ ] API 壓力測試
  - [ ] 正式發布

渲染效果:

  • [ ] 專案上線
    • [x] 購買網域
    • [x] 設定伺服器
    • [ ] 效能測試
    • [x] 首頁載入速度
    • [ ] API 壓力測試
    • [ ] 正式發布

巢狀可以多層疊加,不過建議別超過 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] @Alice 確認需求文件終版
- [ ] @Bob 完成技術方案審查
- [ ] @Carol 產出測試案例
- [ ] 全組 本週五前完成程式碼走查

發布清單

每次發版前對著列表逐項確認,不容易遺漏:

## 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