Chapter 02 / 10

标题、段落与文本格式

深入掌握 Markdown 的基础排版单元:标题层级、段落规则与多种文字强调方式

标题(Headings)

标题是文档结构的骨架。Markdown 提供两种标题语法,两者在 HTML 输出上完全等价,但推荐统一使用 ATX 风格。

ATX 标题(推荐)

# 号前缀表示标题级别,1个#对应 H1,最多 6 个#对应 H6:

源码
# 一级标题(H1)
## 二级标题(H2)
### 三级标题(H3)
#### 四级标题(H4)
##### 五级标题(H5)
###### 六级标题(H6)
生成的 HTML
<h1>一级标题(H1)</h1>
<h2>二级标题(H2)</h2>
<h3>三级标题(H3)</h3>
<h4>四级标题(H4)</h4>
<h5>五级标题(H5)</h5>
<h6>六级标题(H6)</h6>

一级标题(H1)

二级标题(H2)

三级标题(H3)

四级标题(H4)

ATX 标题的细节规则

ATX 标题有一些容易被忽视的细节:

必须有空格
# 和标题文字之间必须有至少一个空格。#标题 不会被解析为标题(CommonMark 规范要求),而是当作普通文字。这与某些旧版解析器的行为不同,注意兼容性。
结尾可有可无的 #
ATX 标题末尾可以加任意数量的 #,它们会被忽略,不影响标题级别。## 二级标题 #### 二级标题 等价。纯粹是视觉上的装饰。
标题前需要空行(推荐)
CommonMark 规范不要求标题前有空行,但实践中强烈推荐:标题前后各加一个空行,使文档结构更清晰,且避免某些解析器产生歧义。markdownlint 的 MD022 规则就是检查这一点的。
标题内可使用内联格式
标题内部可以使用内联格式(加粗、斜体、行内代码等),但通常不推荐在标题中过度使用格式化,保持标题简洁即可。

Setext 标题(了解即可)

Setext 风格用下划线标记,只支持 H1 和 H2,是更古老的写法:

源码
一级标题
========

二级标题
--------
渲染效果

一级标题

二级标题

下划线只需要至少 1 个字符(=-)就有效,长短不限。Setext 风格目前只在旧文档中出现,新文档统一用 ATX 风格。

WARNING(歧义陷阱)Setext 标题和水平分隔线的语法有歧义:如果一行文字后面跟着 ---,会被解析为 Setext H2,而不是"文字后面跟一条分隔线"。这是初学者常踩的坑。要让 --- 成为分隔线,必须确保它上面是一个空行。

标题层级的最佳实践

# ✅ 正确:层级递进,从 H1 开始
# 文档标题(H1,整个文档只有一个)
## 第一章(H2)
### 1.1 子节(H3)
#### 1.1.1 更细分节(H4,尽量少用)

# ❌ 错误:跳级(从 H1 直接到 H3)
# 文档标题
### 子节  # 跳过了 H2,违反了层级语义
INFO(SEO 与可访问性)标题层级不只是视觉问题,还有 SEO(搜索引擎优化)和可访问性意义。屏幕阅读器会用标题导航文档,搜索引擎会据此理解文档结构。H1 应该只有一个,H2/H3 数量不限,但应保持层级逻辑清晰。

段落(Paragraphs)

段落是 Markdown 中最常见的块级元素。理解段落的解析规则,能避免很多初学者的困惑。

段落的定义

一个段落是由一个或多个连续的文本行组成的,段落之间用一个或多个空行分隔。

源码
这是第一行文字。
这是第二行文字,
与第一行合并成一个段落。

这是第二个段落,
由空行和前面分隔。
渲染效果

这是第一行文字。这是第二行文字,与第一行合并成一个段落。

这是第二个段落,由空行和前面分隔。

这个行为称为"软换行折叠"(Soft Wrap):在同一段落内的换行符,会被转换成空格,将多行内容合并为一行。这是 Markdown 继承自 HTML 的行为——HTML 中换行符也会被折叠为空格。

强制换行(Hard Line Break)

如果需要在段落内部强制换行(不开新段落),有两种方式:

方式语法优劣
行末两个空格行尾加 (两个空格)不可见,容易被编辑器自动删除,不推荐
行末反斜杠行尾加 \可见,CommonMark 支持,推荐
HTML br 标签<br><br/>最可靠,但混入 HTML
第一行(行末有反斜杠)\
第二行(在同一段落内换行)

等价写法(行末有两个空格,不可见):
第一行
第二行
TIP在大多数技术写作场景中,如果需要换行,通常意味着应该开始一个新段落,或者使用列表。强制换行的使用场景其实很少——主要用于诗歌、歌词、地址等特殊格式内容。

段落缩进的注意事项

Markdown 段落前不能缩进(0-3 个空格可以,4 个或以上空格会被解析为代码块):

# 正确:普通段落(0-3 个空格前缀都是段落)
这是正常段落。
 这也是正常段落(1个空格)。
   这也是正常段落(3个空格)。

# 错误:被解析为代码块!
    这行有4个空格缩进,会变成代码块。

文本强调(Text Emphasis)

Markdown 提供了多种方式强调文本,底层对应不同的 HTML 语义标签。理解 HTML 语义有助于更好地选择合适的强调方式。

加粗(Bold / Strong)

用双星号或双下划线包裹,对应 HTML <strong> 标签,表示"非常重要的内容":

源码
**用星号加粗**
__用下划线加粗__
中间加粗**单词**示例
渲染效果

用星号加粗

用下划线加粗

中间加粗单词示例

斜体(Italic / Emphasis)

用单星号或单下划线包裹,对应 HTML <em> 标签,表示"强调/着重":

源码
*用星号斜体*
_用下划线斜体_
a*cat*meow(词中加斜体)
渲染效果

用星号斜体

用下划线斜体

acatmeow

加粗与斜体的组合

源码
***加粗斜体(三星号)***
___加粗斜体(三下划线)___
**加粗中的*嵌套斜体***
*斜体中的**嵌套加粗***
渲染效果

加粗斜体(三星号)

加粗斜体(三下划线)

加粗中的嵌套斜体

斜体中的嵌套加粗

星号 vs 下划线:何时用哪个

两者在渲染结果上完全相同,但有使用场景的差异:

推荐原则统一使用星号风格**加粗***斜体*)。原因:下划线在单词内部中间会产生歧义——foo_bar_baz 中的下划线是否表示斜体?CommonMark 规范中,下划线不能在单词中间触发强调,而星号可以。因此,代码变量名等含下划线的文本用下划线风格会有意外行为。
# 下划线风格的歧义问题
_这没问题_          → <em>这没问题</em>
这_中间_有下划线    → 通常不会变成斜体(CommonMark 规范)
foo_bar_baz         → 保持原样(不是斜体),避免了歧义

# 星号风格始终有效
*这没问题*          → <em>这没问题</em>
这*中间*有星号      → 这<em>中间</em>有星号

删除线(Strikethrough)

GFM 扩展语法,用双波浪线包裹,对应 HTML <del> 标签:

源码
~~这段文字被删除~~
价格 ~~¥500~~ ¥299(促销)
渲染效果

这段文字被删除

价格 ¥500 ¥299(促销)

INFO删除线对应 HTML <del> 标签,在 HTML 语义上表示"内容已被删除/不再适用",和 <s>(不准确或不相关的内容)有细微区别,但实际渲染效果相同。CommonMark 标准不包含删除线,这是 GFM 扩展。在不支持 GFM 的环境(如纯 CommonMark 解析器)中,~~文字~~ 会直接显示为字面量。

下划线与高亮(非标准)

标准 Markdown 没有下划线和文字高亮语法。如果必须使用,需要通过内嵌 HTML 实现:

源码
<u>下划线文字</u>
<mark>高亮文字</mark>
<ins>新插入的内容</ins>
<sub>下标</sub>
<sup>上标</sup>
渲染效果

下划线文字

高亮文字

新插入的内容

H2O(下标)

x2(上标)

WARNING在网页排版中,下划线通常意味着"链接"。在技术文档中使用 <u> 下划线会让读者误以为是链接,应谨慎使用。需要强调时,优先考虑加粗或代码格式。高亮(<mark>)在 GitHub 不会渲染为高亮色,GitHub 过滤了大多数 style 属性。

转义字符(Escaping)

当你想在 Markdown 中显示有特殊含义的字符(不让其作为语法解析)时,在字符前加反斜杠 \ 进行转义:

源码
\*这不是斜体\*
\# 这不是标题
\[这不是链接\]
\`这不是代码\`
1\. 这不是有序列表
渲染效果

*这不是斜体*

# 这不是标题

[这不是链接]

`这不是代码`

1. 这不是有序列表

可以转义的字符完整列表

CommonMark 规范中,以下字符可以用 \ 转义:

! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~

其他字符前面的反斜杠会被当作字面量的反斜杠显示,不会消失。例如 \a 会显示为 \a

TIP在代码块(围栏代码块和缩进代码块)内部,反斜杠不起转义作用,所有字符都按字面量显示。所以如果你要展示 Markdown 语法本身,最好把它放在代码块里。

HTML 字符实体(HTML Entities)

Markdown 文档中可以直接使用 HTML 字符实体,常用于显示特殊符号:

命名实体

实体写法符号用途
&amp;&与号(& 在 HTML 中有特殊含义)
&lt; / &gt;< >尖括号(避免被解析为 HTML 标签)
&nbsp;(不换行空格)强制空格,防止换行
&copy;©版权符号
&reg;®注册商标
&trade;商标符号
&mdash;破折号(Em Dash)
&ndash;连接号(En Dash)
&hellip;省略号
&laquo; / &raquo;« »书名号/引号

数字实体

也可以用数字编码(十进制或十六进制)表示字符:

# 十进制
&#169;   → © (版权符号,Unicode 169)

# 十六进制
&#xA9;   → © (版权符号,十六进制 A9)
&#x1F600; → 😀 (emoji 也可以用数字实体)
INFO现代 UTF-8 文档中,直接输入特殊字符(如 ©、—、…)比使用 HTML 实体更直观。HTML 实体主要用于:① 在 HTML 属性中避免字符冲突;② 在某些不支持 UTF-8 的旧系统中使用。日常写 Markdown 时,直接输入特殊字符即可。

内联代码(行内代码)

虽然完整的代码块在第5章讲解,但内联代码是文本格式的一部分,值得在这里介绍。用反引号 ` 包裹的内容会以等宽字体显示:

源码
运行 `npm install` 安装依赖。
变量名 `userName` 不要用 `user_name`。
配置文件在 `~/.config/app.json`。
渲染效果

运行 npm install 安装依赖。

变量名 userName 不要用 user_name

配置文件在 ~/.config/app.json

内联代码内部的 Markdown 语法会被忽略,所有字符都按字面量显示。这让它非常适合展示含有 Markdown 特殊字符的内容。

格式化的语义与用法建议

Markdown 的格式化符号背后对应 HTML 语义标签。正确理解语义,有助于选择合适的格式:

MarkdownHTML 标签语义适用场景
**text**<strong>非常重要关键信息、警告词汇
*text*<em>强调/着重专有名词首次出现、书名
~~text~~<del>已删除内容废弃选项、修订记录
`text`<code>代码/技术内容命令、变量名、文件路径
<mark>text</mark><mark>高亮/标注关键词高亮
WARNING(常见误用)很多人用加粗(**)来"装饰"文字,或者用斜体来"显示变量名",这混淆了 HTML 语义。正确做法:重要警告信息用加粗,代码/命令/变量名用内联代码(`backtick`)。乱用格式会降低可访问性(屏幕阅读器会将 <strong> 读得更重)。

Markdown 格式化的渲染一致性问题

不同 Markdown 渲染器对某些边界情况的处理不同,以下是需要注意的几个点:

中文字符与强调符号之间的空格

原始 Markdown 规范假设英文语境,强调符号需要紧贴被强调文字,两侧不能有空格。中文和英文混排时可能产生解析问题:

# 可能存在解析问题的写法
这是**重要**内容     ← 大多数解析器能处理
这是 **重要** 内容   ← 两侧有空格,部分解析器不识别

# 更安全的写法
这是**重要**内容(不加空格,紧贴)

强调符号内不能有前导或尾随空格

CommonMark 规范规定:** text **(星号内侧有空格)不会被解析为加粗:

** 这不是加粗 **     → 字面显示 ** 这不是加粗 **
**这才是加粗**       → <strong>这才是加粗</strong>

小结

本章要点