Markdown 段落与换行
段落与换行:空行分段、三种硬换行写法、软换行的平台差异与行尾空白陷阱。
认知导入(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 或编辑器自动清理的项目,行尾空格写法会被清除,统一改用反斜杠;块级元素之间留空行既是可读性也是正确性要求。