在 Icarus 主题中实现黑白主题切换教程

在 Icarus 主题中实现黑白主题切换教程

适用于 Hexo + Icarus ≥ 3.x


1️⃣ 写在前面

Icarus 主题优雅,但 官方并未提供主题便捷切换的 方法,很多同学:

  • 不会 Styl → CSS 编译
  • 切换主题时 页面闪屏
  • 返回主页 按钮状态错乱
  • 黑夜主题 黄色导航栏丢失

本篇一次性解决以上痛点,最终效果如本博客


2️⃣ 方案总览

步骤作用文件
① 编译 CSS把官方 .styl 变为 .cssdist/css/
② 变量驱动用 CSS 变量换色,0 闪屏theme-vars.css
③ JS 绑定按钮事件 & PJAX 缓存修复theme-toggle.js
④ 按钮插入放在搜索按钮前navbar.jsx

3️⃣ 第 ① 步:把官方 .styl 编译成 .css

3.1 安装依赖(一次性)

1
2
cd themes/icarus          # 或 node_modules/hexo-theme-icarus
npm ci # 安装 stylus 等依赖

3.2 一键编译

1
npm run build:css         # 输出 dist/css/default.css & cyberpunk.css

如果提示 Missing script,直接跑:

1
npx stylus source/css/ -o dist/css/ --compress

3.3 复制到博客

将生成的 css 文件复制到你的资源文件夹。

1
cp dist/css/*.css  ../../source/css/

4️⃣ 第 ② 步:CSS 变量 换色

4.1 新建文件

source/css/theme-vars.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* 主题切换核心动画 */
:root {
--bg: #ffffff;
--fg: #111111;
--card: #ffffff;
--border: #e5e5e5;
--link: #3273dc;
--shadow: 0 2px 6px rgba(0, 0, 0, .06);
--radius: 8px;
--font: 'Ubuntu', sans-serif;
--t-speed: .6s;
}

[data-theme="dark"] {
--bg: #0d1117;
--fg: #c9d1d9;
--card: #161b22;
--border: #30363d;
--link: #58a6ff;
--shadow: 0 2px 12px rgba(0, 255, 255, .2);
--radius: 12px;
--font: 'Oxanium', sans-serif;
}


html,
body,
.navbar,
.card,
.section,
.widget,
.article,
.article-meta,
.content,
.footer {
transition: background var(--t-speed) cubic-bezier(.4, 0, .2, 1),
color var(--t-speed) cubic-bezier(.4, 0, .2, 1),
box-shadow var(--t-speed) cubic-bezier(.4, 0, .2, 1);
}

/* 加载时淡入 */
body {
animation: fadeIn var(--t-speed) ease-in-out;
}

@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}

5️⃣ 第 ③ 步:新建切换脚本

source/js/theme-toggle.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
(function () {
const STORAGE_KEY = 'icarus-theme';
const icon = document.getElementById('theme-icon');
const lightLink = document.getElementById('theme-light');
const darkLink = document.getElementById('theme-dark');

// 如果元素不存在,直接退出
if (!icon || !lightLink || !darkLink) return;

// 初始化主题
let theme = localStorage.getItem(STORAGE_KEY) || 'light';
applyTheme(theme);

// 应用主题函数
function applyTheme(t) {
document.documentElement.setAttribute('data-theme', t);
lightLink.disabled = t === 'dark';
darkLink.disabled = t === 'light';
icon.className = t === 'dark' ? 'fas fa-sun' : 'fas fa-moon';
localStorage.setItem(STORAGE_KEY, t);
}

// 绑定主题切换事件
document.addEventListener('click', (e) => {
if (e.target.closest('#theme-toggle')) {
theme = theme === 'light' ? 'dark' : 'light';
applyTheme(theme);
}
});

// 处理页面加载完成后的主题应用
document.addEventListener('DOMContentLoaded', () => {
// 确保在页面加载完成后应用主题
setTimeout(() => {
document.documentElement.setAttribute('data-theme', theme);
}, 100);
});

// 处理 PJAX 加载后的主题应用
document.addEventListener('pjax:complete', () => {
setTimeout(() => {
document.documentElement.setAttribute('data-theme', theme);
}, 100);
});
})();;

6️⃣ 第 ④ 步:把按钮插到搜索按钮前

layout/common/navbar.jsx
<div class="navbar-end"> 末尾、搜索按钮 之前

1
2
3
4
5
6
7
<div class="navbar-end">
{showSearch ? <a class="navbar-item search" ... /> : null}
{/* 主题切换按钮 */}
<a class="navbar-item" id="theme-toggle" title=" 切换主题 ">
<i id="theme-icon" class="fas fa-moon"></i>
</a>
</div>

7️⃣ 第 ⑤ 步:把文件挂到 <head>

layout/common/head.jsx

1
2
3
4
5
6
7
<link data-pjax rel="stylesheet" href={url_for('/css/' + variant + '.css')} />
<Plugins site={site} config={config} helper={helper} page={page} head={true} />

<!-- 主题切换 -->
<link rel="stylesheet" href="/css/default.css" id="theme-light" />
<link rel="stylesheet" href="/css/cyberpunk.css" id="theme-dark" disabled />
<script defer src="/js/theme-toggle.js"></script>

8️⃣ 一键测试

1
hexo clean && hexo s
  • 点击右上角 🌙 → ☀️0.6 s 过渡
  • 进入文章 → 返回主页 → 按钮状态 零延迟
  • 黑夜主题:导航栏、页脚、按钮 官方主题配色·

9️⃣ 常见问题 FAQ

现象原因解决
按钮点击无反应按钮 id 写错 / JS 没加载控制台 document.getElementById('theme-toggle') 检查
黄色没出现没覆盖官方 CSS确认 cyberpunk.css 已放 source/css
页面全白兜底 * {} 覆盖了图片用上方 修正版 CSS

🔟 结语

至此,你拥有:

  • 官方 Cyberpunk 主题随心切换

  • 0.6 s 丝滑过渡

    特别提醒:代码块的主题推荐使用 github-vsc 不然会导致黑夜和白天的样式问题。

在 Icarus 主题中实现黑白主题切换教程

http://example.com/2025/08/15/在 Icarus 主题中实现黑白主题切换/

作者

Xuzx-Ricky

发布于

2025-08-15

更新于

2025-08-20

许可协议


评论