Markdown 段落详解:空行、换行与多平台兼容指南

Markdown 段落是什么?比你想的简单

Markdown 里的段落(paragraph)可能是整个语法中最"不像语法"的部分——你不需要任何特殊标记,直接写文字就行。段落之间的分隔靠的是空行,也就是说,只要两段文字之间有一个完全空白的行,它们就会被渲染成两个独立的段落。

说白了,Markdown 段落就是一行或多行连续的文本,段落之间用一个或多个空行隔开。这一规则从 John Gruber 在 2004 年设计 Markdown 的时候就定下来了,到现在也没变过。

渲染的时候,每个段落会被包在 <p> 标签里。所以你在 Markdown 里写:

这是第一段。可以写很多内容,
甚至跨行也没关系。

这是第二段。中间有个空行。

渲染出来的 HTML 是:

<p>这是第一段。可以写很多内容,
甚至跨行也没关系。</p>
<p>这是第二段。中间有个空行。</p>

这里有个初学者经常忽略的点:段落内连续的几行文字会被合并成一行。也就是说,你在编辑器里敲的回车,在不加任何处理的情况下,渲染出来不会换行——多行会变成一行。

段落创建:空行就是一切

创建段落的方法只有一个:在两段文字之间留一个空行。

第一个段落的内容。

第二个段落的内容。

就这么简单。没有标签、没有标记、没有缩进。空行就是段落分隔符。

有几个细节值得注意:

  • 空行的定义:一个完全空白的行,或者只包含空格和制表符的行,都算空行。所以即使你不小心在空行上多打了一个空格,它依然能正常分隔段落
  • 多个空行 = 一个空行:不管你连续留了几个空行,渲染结果都一样——就是两个段落之间有一段间距。Markdown 不会因为你留了三个空行就让间距变成三倍
  • 段落不要缩进:这跟传统中文写作习惯不一样。Markdown 段落开头不需要缩进,也不应该缩进——前面加空格或 Tab 可能会导致内容被解析成代码块(4 个空格 = 代码块),或者产生意想不到的缩进效果

说实话,我刚开始用 Markdown 的时候也犯过这个错——习惯性地在段落开头加两个全角空格,结果在 GitHub 上一看,全变成了奇怪的缩进。后来才明白 Markdown 的设计哲学就是靠空行来分段,不靠缩进。

段落内换行:三种方法

段落之间的分隔用空行,但如果我想在同一段落内换行呢?比如写一首诗,或者排版一个地址。这里有三种常用方法:

方法一:行尾双空格(最经典)

在要换行的位置,先打两个空格,再按回车。

第一行··
第二行

(上面用 ·· 表示两个空格,实际写的时候就是普通空格)

这两个空格会被渲染成 <br> 标签,实现段落内换行。这个方法来自 Markdown 的原始设计,所有主流解析器都支持。

但这里有个坑:行尾空格在很多编辑器里是看不见的,而且有些编辑器会自动帮你删掉行尾空格。VS Code 默认就会这样做。如果你发现行尾双空格不生效,先检查一下编辑器设置里有没有"去除行尾空格"的选项。

方法二:行尾反斜杠(更直观)

在行尾加一个反斜杠 \ 再回车:

第一行\
第二行

这个方法的好处是反斜杠肉眼可见,不用担心被编辑器偷偷删掉。它是 CommonMark 规范支持的标准写法,GitHub、GitLab、Obsidian 都支持。

不过不是所有解析器都认这个。比如一些老版本的 Markdown 解析器可能不支持行尾反斜杠换行。如果你需要兼容一些不太常见的平台,先测试一下。

方法三:HTML <br> 标签(最通用)

直接用 HTML 的换行标签:

第一行<br>
第二行

只要你的 Markdown 解析器允许内联 HTML(绝大多数都允许),这个方法就能用。它的好处是语义明确,不存在兼容性问题。缺点是... 它不算是 Markdown 语法,而是混入了 HTML。

实际使用中,我个人的习惯是:在 GitHub 和大多数平台上用反斜杠(可见、可靠),在需要最大兼容性的时候用 <br>。行尾双空格虽然经典,但因为不可见,实在容易出问题。

不同平台的段落行为差异

这可能是最容易让人困惑的部分——不同平台对段落和换行的处理方式不完全一样。我整理了一个对比表:

平台段落分隔段落内换行备注
GitHub (.md 文件)空行行尾空格 / \ / <br>标准 GFM 行为
GitHub Issues/PR空行直接回车即换行和 .md 文件行为不同!
Typora空行直接回车即换行(所见即所得模式)跟标准 Markdown 有差异
Obsidian空行行尾空格 / \ / <br>严格模式需手动换行
VS Code 预览空行行尾空格 / \ / <br>取决于预览插件
GitLab空行行尾空格 / \ / <br>标准 GFM 行为

重点说一下 GitHub Issues/PR 和 .md 文件的区别。在 GitHub 的 Issues、Pull Request、Discussion 这些评论区域里,你直接按回车就能换行——这跟标准的 Markdown 行为不一样。但在仓库里的 .md 文件中,你必须要用行尾空格或反斜杠才能换行。这个差异一开始挺让人迷惑的。

Typora 的情况也类似。Typora 在所见即所得模式下,回车就直接换行了,因为它的编辑器帮你处理了换行逻辑。但当你把同一个文件放到 GitHub 或其他平台上时,那些单独的回车可能就不会换行了。

段落和其他元素的交互

Markdown 里的段落不是孤立存在的,它和很多其他元素有交互关系,了解这些能帮你避免一些莫名其妙的问题。

段落和列表

列表项里可以包含段落,但需要缩进 4 个空格或 1 个 Tab:

- 第一个列表项

    这是列表项内的第二段。注意前面有 4 个空格。

- 第二个列表项

如果不缩进,那个"第二段"会被当成普通段落,脱离列表。

段落和引用块

引用块里的段落和外面一样,用空行分隔:

> 引用块里的第一段。
>
> 引用块里的第二段。注意空行上也要加 `>`。

注意空行上的 > ——不加的话,引用块会被打断成两个独立的引用。

段落和代码块

如果你在段落文字前面加了 4 个空格或者 1 个 Tab,它就不再是段落了——它会被解析成一个代码块。这是新手特别容易踩的坑:

这是普通段落。

    这变成了代码块,因为前面有 4 个空格。

段落和标题

标题前后建议留空行。虽然有些解析器不要求,但养成这个习惯能避免很多兼容性问题:

## 这是一个标题

标题下面的段落内容。

常见问题与排查

为什么我的段落没有换行?

最常见的两个原因:

  1. 没有留空行——段落之间必须有一个完全空白的行
  2. 空行上有不可见的字符——可能是空格或 Tab,虽然这些在规范中算空行,但某些解析器可能处理不一致

为什么多行文字渲染成了一行?

这是标准 Markdown 行为——段落内的连续行会被合并成一行。如果你想在段落内换行,用前面说的三种方法之一。

有一次我在 Obsidian 里写一篇笔记,连续写了好几行都没换行,以为是 Obsidian 的 bug。后来才明白这就是 Markdown 的设计——行内的换行符被忽略了,除非你用行尾空格或反斜杠明确告诉它"这里要换行"。

为什么我的段落变成了代码块?

段落前面有 4 个或以上空格,或者 1 个或以上 Tab。检查一下段落开头是不是不小心多打了空格。

连续多个空行为什么没效果?

Markdown 规范里,多个连续空行等价于一个空行。如果你确实需要更大的间距,要用 HTML 的方式处理(比如多个 <br> 或者 CSS),不能靠堆空行。

行尾双空格不生效怎么办?

先检查编辑器是不是自动删除了行尾空格。VS Code、Sublime Text 等编辑器默认会这么做。你可以在编辑器设置中关闭这个功能,或者改用反斜杠和 <br> 这两种替代方案。

Markdown 段落的完整参考表

操作语法说明
创建段落段落之间留空行一个或多个空行效果相同
段落内换行行末加两个空格再回车最经典的方法,所有解析器支持
段落内换行行末加 \ 再回车CommonMark 支持,更直观
段落内换行使用 <br> 标签HTML 方式,兼容性最好
多段落列表项列表项内缩进 4 空格第二段起的段落需缩进
引用块内多段落空行上也加 >保持引用连续性

参考来源