Markdown 折叠:details 与 summary 的写法
Markdown 本身没有折叠语法,要靠原始 HTML 来写,也就是一个 <details> 容器加一行 <summary> 标题,并且在标题后面留一个空行,里面的 Markdown 才会继续被解析。GitHub 和妙言的预览都能用,代价是源码有一半是 HTML,遇到会去掉原始 HTML 的渲染器,就只剩下文字。
基本写法
<details>
<summary>构建步骤</summary>
1. 安装依赖。
2. 运行 `make build`。
```bash
make test
```
</details>
<details> 是容器,<summary> 是一直可见的标题,标题之后的内容在点击前都是隐藏的。想默认展开就加 open 属性,写成 <details open>;MDN 说明 open 是布尔属性,所以 open="false" 依然是展开,要收起必须把整个属性删掉。
GitHub 文档给出的也是同样的结构,</summary> 后面留空行,里面可以放代码块,如果同一篇内容也要发到 GitHub,照这个写法两边表现一致。
为什么要留空行
空行不是排版习惯,而是由 CommonMark 处理 HTML 的方式决定的。以 <details 或 <summary 开头的行会开启一个 HTML 块,规范把这两个名字都列在会开启 HTML 块的标签里,这种块到第一个空行才结束,块里的内容原样输出,不再按 Markdown 解析。
所以下面这样写是不行的。
<details>
<summary>更多</summary>
**这不是粗体**,星号会原样显示。
</details>
粗体那一行仍属于 HTML 块,星号就被原样打印出来;在 </summary> 后面加一个空行,HTML 块就在那里结束,下一段重新按 Markdown 解析,</details> 前面也要再留一个空行,免得闭合标签和最后一段粘在一起。
标题行也是同样的道理,<summary> 那一行属于 HTML 块,里面的 Markdown 不会转换,要加粗就写 <b>构建</b>,要写代码就用 <code>make</code>,不要写 **构建** 或反引号。
嵌套和能放什么
<details> 可以嵌套,外层内容和内层开始标签之间留一个空行,每一层的标签各占一行。
<details>
<summary>各平台说明</summary>
通用的建议写在这里。
<details>
<summary>macOS</summary>
macOS 的细节。
</details>
</details>
空行留对之后,列表、表格、图片和围栏代码都能放进去,标题也可以,只是后面有个注意点。MDN 还提到 name 属性,相同 name 的多个 <details> 同一时刻只能展开一个,不用脚本就能做手风琴。妙言会把这个属性原样交给系统的 WebKit,MDN 的兼容数据显示 Safari 从 17.2 开始支持,GitHub 的文档没有提到它,所以手风琴只适合在妙言里看的笔记。
妙言怎么渲染
V4.5.0 里妙言用 cmark-gfm 解析 Markdown,输出 HTML 时打开了允许原始 HTML 的选项(CMARK_OPT_UNSAFE),所以 <details> 块原样到达预览,由 WebKit 画成系统自带的折叠控件,预览样式只给 summary 加了手型光标和一点左内边距。
在编辑器里输入 /fold 再按 Tab 就会插入这段结构,内容就是上面那个模板,包含 <details>、带选中占位文字的 <summary>、一个空行、一行正文和结束标签。Markdown 语法速查与 GFM 差异里把这个快捷输入和其他斜杠命令放在一起列了。
有两处容易踩坑。一是折叠状态下的标题是隐藏的,预览的目录用的是会跳过隐藏标题的选项,所以这样的标题在展开之前可能不会出现在目录里;二是从网页复制折叠区块再粘贴时,妙言的 HTML 转 Markdown 会把 details 和 summary 当成普通容器,标题和内容变成普通段落,折叠效果没有了,想保留就自己敲 HTML。
导出和打印
「导出」子菜单有 HTML、图片和 PDF,V4.5.0 里图片和 PDF 都从预览当下的样子出发。图片是给预览页面截一张快照,PDF 是把预览当前的 HTML 拷进打印流程,中间没有任何展开 <details> 的处理。点击标题时浏览器会给这个元素加上或去掉 open 属性,所以在预览里点开的块导出时是展开的,收起的块导出后只剩标题那一行。如果导出时只开着编辑区,妙言会先打开预览,这时没写 open 的块都是收起的。
内容必须出现在纸面上时,这些块就写成 <details open>,预览和导出里都会默认展开,PDF 的其他设置见在 Mac 上把 Markdown 转成 PDF。
可访问性
原生 <details> 是一个展开控件,按 MDN 的说明,读者可以点击它,或聚焦后按空格键切换,元素里的内容会成为 <summary> 的可访问描述,比自己拼的开关要好,前提是标题写得有用。标题写清里面是什么,比如「Linux 构建步骤」,不要写「点击这里」或「更多」,也要写短,因为收起时只有这行文字可见。
读者完成任务必须看到的信息不要折叠,折叠适合可选的细节,比如日志、很长的输出或某个平台的补充说明。
容易出错的地方
- 块里的 Markdown 显示成原始符号,多半是
</summary>后面或</details>前面少了空行。 - 在妙言里正常,换个地方变成一堆平铺文字,是那个渲染器会去掉或转义原始 HTML,要在读者实际看的地方测试。
- PDF 里少了内容,是导出时块处于收起状态,先在预览里点开,或者加
open属性。 - 折叠区里的围栏代码块乱了,在开头围栏前留一个空行,并让围栏和周围文字缩进一致。
常见问题
GitHub 支持折叠吗?
支持,GitHub 文档以 issue 评论为例描述了 <details> 和 <summary> 的写法,用 open 默认展开。
标题行里能写 Markdown 标题吗?
不能转换,标题行属于 HTML 块,改用纯文字或 HTML 标签,正文里的标题没有问题。
有没有纯 Markdown 的折叠写法?
CommonMark 和 GFM 都没有,所以各个渲染器都靠这个 HTML 元素。
