前置知识: Markdown

Markdown 段落与换行

6 min入门

段落与换行:空行分段、三种硬换行写法、软换行的平台差异与行尾空白陷阱。

认知导入(Layer 0 生存层) 前置知识:002 标题语法。 边界说明:段落与换行是 Markdown 的”第一性原理”——空白字符(空行、行尾空格)本身就是语法。本篇要解决的高频困惑只有一个:“为什么我明明换了行,渲染出来却连成一行?” 强制练习:写两行文字(中间不加空行)预览,观察它们被合并成一段;再在第一行行尾敲两个空格后回车,观察换行生效。

1. 段落:空行就是语法

1.1 段落的定义

段落(paragraph)由一个或多个连续的文本行组成,段落之间用一个或多个空行分隔。空行是唯一可靠的分段手段:

这是第一个段落。
它可以连续写多行,仍属于同一段落。

这是第二个段落,与上一段之间隔了一个空行。

渲染结果:

这是第一个段落。它可以连续写多行,仍属于同一段落。

这是第二个段落,与上一段之间隔了一个空行。

1.2 关键认知:源码换行不等于渲染换行

上面例子里,“第一段落”的两行在源码中各占一行,渲染时却被合并成一行(原换行位置替换为一个空格)。这类由换行符引起的合并叫软换行(soft line break):

第一行源码
第二行源码

CommonMark 的标准行为是渲染为一行:第一行源码 第二行源码(换行位置变成一个空格)。想在渲染结果里真正断行,必须使用第 2 节的”硬换行”写法。

类比:Markdown 源码像一份”逐字稿”,其中换行只是给排版员的建议;空行才是明确的”另起一段”指令。

2. 硬换行的三种写法

在同一段落内强制断行(HTML 的 <br>),有三种等价方案:

2.1 行尾两个空格(经典写法)

行尾添加两个及以上空格再回车:

这是第一行(行尾有两个不可见的空格)
这是第二行

这是 CommonMark 与 GFM 通用的标准写法。缺点:行尾空格不可见,容易被编辑器的”保存时去除行尾空白”功能悄悄吃掉(见 5.1 节)。

2.2 行尾反斜杠(CommonMark 写法)

行尾写一个反斜杠 \:

这是第一行\
这是第二行

效果与行尾空格完全相同,但反斜杠肉眼可见,不会被格式化工具误删。推荐在启用 lint/格式化的项目里使用这种写法。注意 GFM 与 CommonMark 均支持;个别老旧渲染器只认空格写法。

2.3 <br> 标签(保底写法)

直接在行尾写 HTML 换行标签:

这是第一行<br>
这是第二行

这是兼容性最强的写法——即使渲染器不支持前两种,只要允许内嵌 HTML 就会生效。也是表格单元格内换行的唯一选择(表格单元格按行内语法解析,见 markdown/100-Table)。

2.4 三种写法对照

写法可见性抗格式化删除兼容性适用场景
行尾两空格不可见差(易被清除)通用手写短文档
行尾 \可见好CommonMark/GFM工程项目文档(推荐)
<br>可见好最广表格内换行、保守兼容场景

3. 软换行的平台差异

“源码里按一次回车到底渲染成什么”,各平台并不一致,这是跨平台文档最常见的困惑来源:

环境段内单个换行的渲染行为
CommonMark/GFM 规范行为合并为一行(换行变空格)
GitHub 仓库内 .md 文件(README 等)同规范:合并为一行
GitHub Issue / Pull Request / Discussion 正文与评论自动渲染为换行
多数静态站点生成器(Hugo、Jekyll 等)同规范:合并为一行

也就是说:同一段源码,粘到 GitHub 的评论框里分行正常,保存成 README 后却连成一行——这不是 bug,而是平台在规范行为之上为评论场景做的便利化处理。写 .md 文件时永远不要依赖”回车即换行”,需要断行就用第 2 节的硬换行写法。

4. 空行与块级元素

空行除了分段,还承担”块级元素分隔符”的角色:

# 标题

这是一个段落。

- 列表项一
- 列表项二

> 引用内容

使用要点:

  • 块级元素之间建议留空行:标题、段落、列表、代码块、表格之间加空行,源码可读性更好,也能规避”前一元素把后一元素吞进去”的解析问题(最典型的是段落文本后紧跟 --- 会变成 Setext 二级标题,见 markdown/020-HeadingSyntax)。
  • 多个空行等同一个空行:渲染时连续空行不会产生更大间距,样式间距由 CSS 决定。
  • 列表项内的段落例外:列表项内嵌段落时,“空行 + 缩进”要配合使用,缩进决定归属,详见 markdown/060-ListSyntax。

5. 常见陷阱

5.1 行尾空格被编辑器或工具清除

很多编辑器默认”保存时删除行尾空白”,markdownlint 的 MD009 规则也会报告行尾空格——两者都会让行尾两空格的硬换行失效。对策:

  • 团队项目统一改用行尾反斜杠 \ 写法;
  • 或在 .markdownlint.json 中为 MD009 配置 br_spaces: 2,并关闭编辑器的行尾空白清理(仅对 Markdown 文件)。

5.2 全角空格不生效

行尾敲的是中文输入法下的全角空格( )时不会被识别为硬换行——语法要求的是 ASCII 空格。排查”空格明明敲了却没换行”时,先把行尾字符切换到英文输入法重打。

5.3 粘贴文本带来隐形单换行

从别处复制的段落常在源码里带单换行,本地预览(部分编辑器按”回车即换行”渲染,如某些笔记软件)看着正常,发布到站点就合并成一行。发布前用目标平台的预览确认。

5.4 想要空行间距却用了空行

Markdown 渲染不会因为多个空行产生更大间距,视觉间距属于 CSS 的职责。用空行控制排版只会让源码变长,正确做法是调整站点样式。

5.5 反斜杠行尾的误伤

**加粗**\ 这样以反斜杠收尾的文本会触发硬换行,导致下一行莫名接排——排查”哪里多出来的换行”时先看行尾反斜杠(详见 markdown/080-EscapeCharacter)。

小结

  • 初学者要点:分段靠空行;段内强制换行用”行尾两空格”或行尾 \;表格里换行用 <br>;源码里按回车渲染时会合并成一行,这是正常行为。
  • 进阶注意:GitHub 的 Issue/评论会把单个换行渲染为换行,但仓库内 .md 文件遵循规范合并为一行——写文件永远用显式硬换行;启用 markdownlint 或编辑器自动清理的项目,行尾空格写法会被清除,统一改用反斜杠;块级元素之间留空行既是可读性也是正确性要求。