前言

Markdown 和 HTML 并不是互相竞争的两种语言。

  • Markdown 负责让我们用简单、易读的纯文本快速写作。
  • HTML 负责描述网页内容的结构和语义。
  • CSS 决定这些结构最终呈现出来的颜色、间距、圆角和动画。
  • JavaScript 则负责更复杂的交互行为。

在 Hexo 中,我们写下的 Markdown 会在构建时被渲染器转换成 HTML,浏览器最终读取的仍然是 HTML。因此,理解两者之间的对应关系,可以帮助我们判断什么时候使用 Markdown,什么时候直接写 HTML。

推荐原则:正文优先使用 Markdown;只有在需要特殊结构或样式时才使用 HTML,并把可复用的外观交给 CSS。


一、Markdown 是怎样变成 HTML 的

以下 Markdown:

1
2
3
## 欢迎来到我的博客

这里有一段包含 **重点内容** 和 [链接](https://example.com) 的文字。

构建后大致会得到:

1
2
3
4
5
<h2>欢迎来到我的博客</h2>
<p>
这里有一段包含 <strong>重点内容</strong>
<a href="https://example.com">链接</a> 的文字。
</p>

浏览器不认识 Markdown 中的 ##**,它真正识别的是 <h2><p><strong> 等 HTML 标签。


二、常用 Markdown 与 HTML 对照

内容 Markdown 对应的 HTML
一级标题 # 标题 <h1>标题</h1>
二级标题 ## 标题 <h2>标题</h2>
段落 空行分隔文本 <p>文本</p>
换行 行末两个空格或 <br> <br>
粗体 **文字** <strong>文字</strong>
斜体 *文字* <em>文字</em>
删除线 ~~文字~~ <del>文字</del>
行内代码 `代码` <code>代码</code>
链接 [名称](地址) <a href="地址">名称</a>
图片 ![说明](地址) <img src="地址" alt="说明">
引用 > 内容 <blockquote>内容</blockquote>
分隔线 --- <hr>

1. 标题

Markdown 使用 # 的数量表示标题层级:

1
2
3
4
# 一级标题
## 二级标题
### 三级标题
#### 四级标题

对应 HTML:

1
2
3
4
<h1>一级标题</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>
<h4>四级标题</h4>

一篇文章通常只有页面标题使用一级标题,正文建议从二级标题开始,这样目录结构更清晰。

2. 段落与换行

Markdown 中用一个空行分隔段落:

1
2
3
这是第一个段落。

这是第二个段落。

对应 HTML:

1
2
<p>这是第一个段落。</p>
<p>这是第二个段落。</p>

如果只需要在同一段内换行,可以使用 <br>。不要为了制造间距连续写很多 <br>,段落间距更适合交给 CSS 的 margin 控制。

3. 强调文字

1
2
3
4
**粗体**
*斜体*
***粗斜体***
~~删除线~~

对应 HTML:

1
2
3
4
<strong>粗体</strong>
<em>斜体</em>
<strong><em>粗斜体</em></strong>
<del>删除线</del>

实际效果:粗体 斜体 粗斜体 删除线

strongem 不只是改变外观,也分别表达“重要”和“强调”的语义。

4. 链接与图片

1
2
3
[访问我的 GitHub](https://github.com/unmyic)

![图片说明](/img/avatar.png)

对应 HTML:

1
2
<a href="https://github.com/unmyic">访问我的 GitHub</a>
<img src="/img/avatar.png" alt="图片说明">

HTML 可以增加 Markdown 不方便提供的属性:

1
2
3
4
5
6
7
8
9
10
<a href="https://github.com/unmyic"
target="_blank"
rel="noopener noreferrer">
在新标签页打开 GitHub
</a>

<img src="/img/avatar.png"
alt="网站头像"
width="160"
loading="lazy">

其中 alt 有助于无障碍阅读,也能在图片加载失败时说明图片内容。

5. 列表

无序列表:

1
2
3
- HTML
- CSS
- JavaScript
1
2
3
4
5
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>

有序列表:

1
2
3
1. 编写文章
2. 本地预览
3. 生成并部署
1
2
3
4
5
<ol>
<li>编写文章</li>
<li>本地预览</li>
<li>生成并部署</li>
</ol>

任务列表属于常见的 GFM(GitHub Flavored Markdown)扩展:

1
2
3
- [x] 完成博客搭建
- [x] 调整主题
- [ ] 继续更新文章
  • [x] 完成博客搭建
  • [x] 调整主题
  • [ ] 继续更新文章

6. 引用

1
2
3
> 我们塑造了工具,此后工具又塑造了我们。
>
> 引用中也可以包含多个段落。

对应 HTML:

1
2
3
4
<blockquote>
<p>我们塑造了工具,此后工具又塑造了我们。</p>
<p>引用中也可以包含多个段落。</p>
</blockquote>

7. 代码

行内代码:

1
使用 `hexo generate` 生成静态页面。

代码块:

1
2
3
4
```javascript
const message = 'Hello, world!';
console.log(message);
```

对应 HTML 的核心结构是:

1
2
3
4
<pre><code class="language-javascript">
const message = 'Hello, world!';
console.log(message);
</code></pre>

代码围栏后的语言名称会帮助高亮插件选择正确的语法规则。

8. 表格

1
2
3
4
5
| 技术 | 作用 |
| --- | --- |
| HTML | 描述结构 |
| CSS | 控制样式 |
| JavaScript | 实现交互 |

对应 HTML 会包含 <table><thead><tbody><tr><th><td> 等标签。HTML 表格还能使用 rowspancolspan 合并单元格,这是普通 Markdown 表格不方便做到的。

9. 转义特殊字符

如果希望显示 Markdown 符号本身,可以在前面添加反斜杠:

1
2
\*这段文字不会变成斜体\*
\# 这也不会成为标题

HTML 中的 <>& 通常分别写成 &lt;&gt;&amp;,避免它们被误认为标签或实体。


三、HTML 能补充哪些功能

Markdown 擅长文章结构,但原生 HTML 提供了更多语义化组件。

1. 折叠内容

1
2
3
4
<details>
<summary>点击查看答案</summary>
<p>这里是默认隐藏的内容。</p>
</details>

实际效果:

点击查看答案

这里是默认隐藏的内容,不需要 JavaScript 就能展开和收起。

2. 高亮、上下标和键盘按键

1
2
3
4
<mark>高亮文字</mark>
H<sub>2</sub>O
x<sup>2</sup>
按下 <kbd>Ctrl</kbd> + <kbd>S</kbd> 保存

实际效果:

高亮文字、H2O、x2,按下 Ctrl + S 保存。

3. 缩写、时间和注音

1
2
3
<abbr title="HyperText Markup Language">HTML</abbr>
<time datetime="2026-07-26">2026 年 7 月 26 日</time>
<ruby><rt></rt><rt></rt></ruby>

实际效果:

HTML

这些标签不仅改变显示方式,也能让机器和辅助阅读设备更准确地理解内容。

4. 图片说明

1
2
3
4
5
6
<figure>
<img src="/img/banner-ocean-v2-2k.webp"
alt="海边背景"
loading="lazy">
<figcaption>为博客设计的海边背景图</figcaption>
</figure>

figurefigcaption 可以把图片、图表或代码示例与说明文字组成一个完整单元。

5. 原生进度与度量

1
2
3
4
5
6
<label>
文章完成进度:
<progress value="75" max="100">75%</progress>
</label>

<meter min="0" max="100" low="40" high="80" value="86">86</meter>

实际效果:


四、用 HTML 与 CSS 制作美化组件

HTML 决定组件里有什么,CSS 决定组件长什么样。下面是一组无需 JavaScript 的文章提示卡片。

HTML

1
2
3
4
5
6
7
<aside class="article-callout article-callout--tip">
<div class="article-callout__icon"></div>
<div>
<strong>写作提示</strong>
<p>优先使用语义清晰的结构,样式可以随时调整。</p>
</div>
</aside>

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.article-callout {
display: flex;
gap: 12px;
padding: 16px 18px;
border: 1px solid rgba(59, 130, 246, 0.25);
border-radius: 14px;
background: rgba(59, 130, 246, 0.08);
}

.article-callout__icon {
color: #3b82f6;
font-size: 22px;
}

.article-callout p {
margin: 4px 0 0;
}

实际效果:

同一个链接也可以通过 CSS 变成按钮:

这里仍然使用 <a> 而不是 <button>,因为它的行为是“跳转到另一个页面”。HTML 标签应当根据功能选择,而不只是根据外观选择。


五、常见 HTML 美化思路

1. 使用 class,不要复制大量行内样式

不推荐:

1
2
3
<p style="color: blue; padding: 10px; border-radius: 8px;">
一段文字
</p>

更推荐:

1
<p class="notice-text">一段文字</p>
1
2
3
4
5
.notice-text {
padding: 10px;
border-radius: 8px;
color: #2563eb;
}

这样修改一次 CSS,就能统一更新所有使用该 class 的内容。

2. 使用 CSS 变量统一主题色

1
2
3
4
5
6
7
8
9
:root {
--accent-color: #3b82f6;
--accent-soft: rgba(59, 130, 246, 0.1);
}

.notice-text {
color: var(--accent-color);
background: var(--accent-soft);
}

如果以后更换网站主题色,只需要修改变量。

3. 同时考虑暗色主题

Butterfly 会在暗色模式下给根节点添加 data-theme="dark",可以这样覆盖:

1
2
3
4
[data-theme='dark'] .notice-text {
color: #93c5fd;
background: rgba(96, 165, 250, 0.12);
}

4. 为手机端添加响应式规则

1
2
3
4
5
6
7
8
9
10
11
.two-column-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}

@media (max-width: 768px) {
.two-column-layout {
grid-template-columns: 1fr;
}
}

桌面端显示两列,手机端会自动变为一列。

5. 尊重“减少动态效果”设置

1
2
3
4
5
6
7
8
9
.floating-card {
transition: transform .25s ease;
}

@media (prefers-reduced-motion: reduce) {
.floating-card {
transition: none;
}
}

这可以减少动画给部分访客带来的不适。


六、在 Hexo 博客中应该写在哪里

1. 只属于一篇文章的结构

直接写在该文章的 Markdown 文件中:

1
source/_posts/文章名称.md

Markdown 与少量 HTML 可以混合书写。

2. 多篇文章都会使用的样式

建议放进独立 CSS 文件:

1
source/css/custom-article.css

然后在 Butterfly 配置的 inject.head 中引入:

1
2
3
inject:
head:
- <link rel="stylesheet" href="/css/custom-article.css">

3. 需要交互行为的组件

JavaScript 文件可以放在:

1
source/js/custom-component.js

再通过 inject.bottom 引入:

1
2
3
inject:
bottom:
- <script defer src="/js/custom-component.js"></script>

4. 图片和附件

全站通用资源可以放在:

1
2
source/img/
source/downloads/

文章中分别使用 /img/文件名/downloads/文件名 访问。


七、容易遇到的问题

HTML 被显示成普通文字

先确认 HTML 没有放在代码围栏中。代码围栏里的内容只用于展示源码,不会被浏览器执行:

1
2
3
```html
<strong>这里只会展示代码</strong>
```

如果要真正渲染,就不要添加代码围栏。例如,下面这行在 Markdown 源文件中直接使用了 <strong> 标签:

这里会被渲染为粗体,而不是代码。

部分 Markdown 渲染器会出于安全考虑禁用原始 HTML,这时还需要检查渲染器的 htmlsanitizedompurify 配置。

标签嵌套错误

HTML 标签通常需要成对闭合,并按相反顺序结束:

1
2
3
4
5
<!-- 正确 -->
<strong><em>文字</em></strong>

<!-- 错误 -->
<strong><em>文字</strong></em>

样式影响了整个网站

避免使用过于宽泛的选择器:

1
2
3
4
5
6
7
8
9
/* 可能改变全站所有段落 */
p {
color: blue;
}

/* 只改变指定组件里的段落 */
.article-callout p {
color: blue;
}

不要直接信任外部 HTML

HTML 可以加载资源、创建表单或执行脚本。不要把不可信来源提供的 HTML 或 JavaScript 原样加入博客。


八、选择 Markdown 还是 HTML

场景 推荐方式
标题、段落、列表、引用 Markdown
普通链接与图片 Markdown
代码块和简单表格 Markdown
折叠面板、图片说明、进度条 HTML
按钮、卡片、多列布局 HTML + CSS
播放器、弹窗等复杂交互 HTML + CSS + JavaScript
多篇文章复用的视觉样式 独立 CSS 文件

Markdown 让写作保持简单,HTML 提供更精确的结构,CSS 和 JavaScript 则扩展了网页的表现力。它们最理想的关系不是互相替代,而是各自承担擅长的部分。

当一篇文章只需要清晰表达内容时,Markdown 已经足够;当内容需要特殊语义、布局或交互时,再逐步加入 HTML、CSS 与 JavaScript。这种方式既能保持源文件可读,也能让博客拥有自己的视觉风格。