HTML 嵌入

Markdown 允许在文档里直接写 HTML。这既是它扩展性的来源,也是它风险的来源:同一份源码放到不同平台上,可能得到完全不同的结果——有的平台删掉标签,有的平台让标签生效但样式对不上。这一页要讲清三件事:哪些位置可以写 HTML、HTML 块到哪里为止、以及「解析器保留」和「平台放行」的区别。

行内 HTML 与块级 HTML

行内 HTML 写在段落中间,和文字混排:

段落里的 <span class="x">行内标签</span> 文字。
<p>段落里的 <span class="x">行内标签</span> 文字。</p>

块级 HTML 独占一行,比如 div、table、details:

这里是段落
<div class="note">这是自定义 HTML 区块</div>
<p>这里是段落</p>
<div class="note">这是自定义 HTML 区块</div>

注意第二例:「这里是段落」本来可以继续往下写,但块级 HTML 一出现,当前段落就被截断了。块级 HTML 总是自己开一段。

HTML 块在哪里结束

这是内嵌 HTML 最反直觉的一点:HTML 块在空行处结束。空行之后的 Markdown 会被重新当作 Markdown 解析:

<div>

**粗体**会解析

</div>
<div>
<p><strong>粗体</strong>会解析</p>
</div>

有人以为「HTML 块里的内容不会被解析」,其实不是——只是解析器要等到空行才知道这块 HTML 结束了。

反过来,没有空行就不会结束。下面这行的「紧跟的段落」被 HTML 块吃掉了,根本没有变成段落:

<div>区块</div>
紧跟的段落
<div>区块</div>
紧跟的段落

所以在 HTML 块后面补一行新内容时,别忘了先空一行。

解析器不替你过滤

Markdown 解析器不会删除任何标签:

<script>alert(1)</script>
<script>alert(1)</script>

什么时候该用 HTML

内嵌 HTML 真正的用武之地,是 Markdown 表达不了的东西:带标题属性的图片、需要折叠展开的详情块、video、iframe 这类标签,以及必须靠内联样式才能实现的排版。普通的加粗、列表、表格、引用,一律优先用 Markdown 语法——它们的跨平台兼容性高得多,出问题时排查成本也低得多。

常见坑

写法实际渲染原因
段落中间插一行块级 HTML段落被截断HTML 块会打断段落
HTML 块后紧跟一行文字文字被吞进 HTML 块没有空行就不会结束
HTML 块内空一行再写 Markdown空行后的内容会被解析HTML 块在空行处结束
写 <script> 标签标签原样保留解析器不做安全过滤
段落中间写行内 HTML正常显示行内标签在段落内解析

练习

把下面这段内容改写成 Markdown,要求:第一句是普通段落;接着用一行块级 HTML 插入一个提示框;提示框之后空一行再写最后一句,最后一句里的加粗要能正常渲染。

这一段是普通说明。

提示:请先完成身份验证。

最后一步:点击**提交**按钮完成操作。
行内标签

解题思路: 提示框用一行块级 HTML 表示,关键在它后面的空行:块级 HTML 会在空行处结束,没有空行的话,最后一句会被当成 HTML 块的一部分吞掉,根本不会渲染成段落,句中的加粗自然也失效。

详细步骤:

  1. 第一句直接写成普通段落,不加任何标记。
  2. 空一行,另起一行写块级 HTML,写作 <div class="note">提示:请先完成身份验证。</div>,整行只放这一个标签。
  3. 紧接着空一行。这一行是必需的,它让 HTML 块结束。
  4. 最后一句写成普通段落,加粗写作 **提交**。
  5. 检验:渲染后有三段内容——普通说明、提示框、加粗的收尾句;加粗正常生效,没有被 HTML 块吞掉。

最终答案:

这一段是普通说明。

<div class="note">提示:请先完成身份验证。</div>

最后一步:点击**提交**按钮完成操作。

小结

读完这一页,你应当能分清行内 HTML 和块级 HTML,能说清 HTML 块在空行处结束、块级 HTML 会打断段落,能解释为什么文档里写了 <script> 也不会被 Markdown 删掉,也能在排版错乱时先去找「少了空行」这一条。

发现内容有问题?

告诉我们哪里需要改进。