Next 主题添加可切换的暗黑模式
本文首发于 Clay 的技术博客
前言
Next 8.x 原生的暗黑模式
Next 8.x 主题已经原生支持暗黑模式,只需要在 Next 的 _config.yml 配置文件中,将相应的开关打开即可(如下所示):
darkmode: true
Next 8.x 主题原生暗黑模式的优缺点:
- 优点:
- 配置非常简单
- 缺点:
- 缺少切换按钮,默认是根据系统偏好(系统是否处于暗黑模式)来决定是否启用
Next 7.x / 8.x 自动添加可切换的暗黑模式
hexo-next-darkmode 插件支持自动添加可切换的暗黑模式,同时支持暗黑模式下的 CSS 样式高度自定义,兼容 Next 7.x 与 8.x 版本。
安装 Hexo 插件
安装 hexo-next-darkmode 插件
$ npm install hexo-next-darkmode --save
配置 Hexo 插件
在 Next 主题的 _config.yml 配置文件里添加以下内容
# Darkmode JS
# For more information: https://github.com/rqh656418510/hexo-next-darkmode, https://github.com/sandoche/Darkmode.js
darkmode_js:enable: truebottom: '64px' # default: '32px'right: 'unset' # default: '32px'left: '32px' # default: 'unset'time: '0.5s' # default: '0.3s'mixColor: 'transparent' # default: '#fff'backgroundColor: 'transparent' # default: '#fff'buttonColorDark: '#100f2c' # default: '#100f2c'buttonColorLight: '#fff' # default: '#fff'isActivated: false # default falsesaveInCookies: true # default: truelabel: '🌓' # default: ''autoMatchOsTheme: true # default: truelibUrl: # Set custom library cdn url for Darkmode.js
isActivated: true:默认激活暗黑/夜间模式,请始终与saveInCookies: false、autoMatchOsTheme: false一起使用
关闭原生的暗黑模式
确保 Next 原生的 darkmode 选项设置为 false,在 Next 的 _config.yml 配置文件中更改以下内容:
darkmode: false
暗黑模式 CSS 样式自定义(可选)
暗黑模式激活后,hexo-next-darkmode 插件会将 darkmode--activated CSS 类添加到 body 标签,可以利用它覆盖插件默认自带的 CSS 样式(如下所示);这样就可以实现暗黑模式 CSS 样式的高度自定义,包括代码块颜色自定义切换等。更多配置内容介绍可以参考官方文档,实现原理分析可以看这里。
.darkmode--activated {--body-bg-color: #282828;--content-bg-color: #333;--card-bg-color: #555;--text-color: #ccc;--blockquote-color: #bbb;--link-color: #ccc;--link-hover-color: #eee;--brand-color: #ddd;--brand-hover-color: #ddd;--table-row-odd-bg-color: #282828;--table-row-hover-bg-color: #363636;--menu-item-bg-color: #555;--btn-default-bg: #222;--btn-default-color: #ccc;--btn-default-border-color: #555;--btn-default-hover-bg: #666;--btn-default-hover-color: #ccc;--btn-default-hover-border-color: #666;--highlight-background: #282b2e;--highlight-foreground: #a9b7c6;--highlight-gutter-background: #34393d;--highlight-gutter-foreground: #9ca9b6;
}.darkmode--activated img {opacity: 0.75;
}.darkmode--activated img:hover {opacity: 0.9;
}.darkmode--activated code {color: #69dbdc;background: transparent;
}
重新构建生成静态文件
Hexo 重新构建生成静态文件后,点击页面上的按钮即可切换暗黑模式,最终演示效果可以看这里。
$ hexo clean$ hexo g -d
Next 8.x 手动添加可切换的暗黑模式
关闭原生的暗黑模式
确保 Next 原生的 darkmode 选项设置为 false,在 Next 的 _config.yml 配置文件中更改以下内容:
darkmode: false
添加 JS 库 Darkmode.js
下载 darkmode.js 或者直接添加 CDN 配置到 Next 的 themes/next/_vendors.yml 文件末尾,这里采用 CDN 配置的方式(如下所示)
darkmode_js:name: darkmode-jsversion: 1.5.7file: lib/darkmode-js.min.js
添加 Darkmode.js 的启用开关
在 Next 的 _config.yml 配置文件添加以下内容,值得一提的是,这里需要注意缩进,第一个 darkmode_js 是在 vendors 栏目下,第二个 darkmode_js 是一个单独的栏目
vendors:# Darkmode.jsdarkmode_js:darkmode_js:enable: true
配置 JS 库 Darkmode.js
编辑 themes/next/layout/_scripts/vendors.njk 文件,将原有的代码删除掉,替换为以下代码即可:
{%- if theme.canvas_ribbon.enable %}<script size="{{ theme.canvas_ribbon.size }}" alpha="{{ theme.canvas_ribbon.alpha }}" zIndex="{{ theme.canvas_ribbon.zIndex }}" src="{{ theme.vendors.canvas_ribbon }}"></script>
{%- endif %}{# Customize darkmode.js - Declaration #}
{%- if theme.darkmode_js.enable %}<script src="{{ theme.vendors.darkmode_js }}"></script>
{%- endif %}{%- for name in js_vendors() %}<script src="{{ url_for(theme.vendors[name]) }}"></script>
{%- endfor %}{# Customize darkmode.js - Invokation #}
{%- if theme.darkmode_js.enable %}
<script>
var options = {bottom: '64px', // default: '32px'right: 'unset', // default: '32px'left: '32px', // default: 'unset'time: '0.5s', // default: '0.3s'mixColor: '#fff', // default: '#fff'backgroundColor: '#fff', // default: '#fff'buttonColorDark: '#100f2c', // default: '#100f2c'buttonColorLight: '#fff', // default: '#fff'saveInCookies: true, // default: true,label: '🌓', // default: ''autoMatchOsTheme: true // default: true
}
const darkmode = new Darkmode(options);
darkmode.showWidget();
</script>
{%- endif %}
更改后的源文件就如上所示,其他内容可以根据实际情况自行更改。添加上面的代码后,暗黑模式的切换按钮默认显示在左下角,如果希望切换按钮显示在右下角,可以参考以下代码:
{# Customize darkmode.js - Invokation #}
{%- if theme.darkmode_js.enable %}
<script>
var options = {bottom: '64px', // default: '32px'right: '32px', // default: '32px'left: 'unset', // default: 'unset'time: '0.5s', // default: '0.3s'mixColor: '#fff', // default: '#fff'backgroundColor: '#fff', // default: '#fff'buttonColorDark: '#100f2c', // default: '#100f2c'buttonColorLight: '#fff', // default: '#fff'saveInCookies: true, // default: true,label: '🌓', // default: ''autoMatchOsTheme: false // default: true
}
const darkmode = new Darkmode(options);
darkmode.showWidget();
</script>
{%- endif %}
暗黑模式 CSS 样式自定义
实现原理分析
从 Next 8.0 开始,已经原生支持代码块 Dark 主题,直接在 Next 的 _config.xml 文件里配置即可(如下所示):
codeblock:# Code Highlight theme# All available themes: https://theme-next.js.org/highlight/theme:light: atelier-forest-lightdark: androidstudioprism:light: prismdark: prism-atom-dark
其中 Next 8.3 源文件 themes/next/source/css/_colors.styl 的内容如下所示:
:root {--body-bg-color: $body-bg-color;--content-bg-color: $content-bg-color;--card-bg-color: $card-bg-color;--text-color: $text-color;--blockquote-color: $blockquote-color;--link-color: $link-color;--link-hover-color: $link-hover-color;--brand-color: $brand-color;--brand-hover-color: $brand-hover-color;--table-row-odd-bg-color: $table-row-odd-bg-color;--table-row-hover-bg-color: $table-row-hover-bg-color;--menu-item-bg-color: $menu-item-bg-color;--btn-default-bg: $btn-default-bg;--btn-default-color: $btn-default-color;--btn-default-border-color: $btn-default-border-color;--btn-default-hover-bg: $btn-default-hover-bg;--btn-default-hover-color: $btn-default-hover-color;--btn-default-hover-border-color: $btn-default-hover-border-color;--highlight-background: $highlight-background;--highlight-foreground: $highlight-foreground;--highlight-gutter-background: $highlight-gutter-background;--highlight-gutter-foreground: $highlight-gutter-foreground;
}if (hexo-config('darkmode')) {@media (prefers-color-scheme: dark) {:root {--body-bg-color: $body-bg-color-dark;--content-bg-color: $content-bg-color-dark;--card-bg-color: $card-bg-color-dark;--text-color: $text-color-dark;--blockquote-color: $blockquote-color-dark;--link-color: $link-color-dark;--link-hover-color: $link-hover-color-dark;--brand-color: $brand-color-dark;--brand-hover-color: $brand-hover-color-dark;--table-row-odd-bg-color: $table-row-odd-bg-color-dark;--table-row-hover-bg-color: $table-row-hover-bg-color-dark;--menu-item-bg-color: $menu-item-bg-color-dark;--btn-default-bg: $btn-default-bg-dark;--btn-default-color: $btn-default-color-dark;--btn-default-border-color: $btn-default-border-color-dark;--btn-default-hover-bg: $btn-default-hover-bg-dark;--btn-default-hover-color: $btn-default-hover-color-dark;--btn-default-hover-border-color: $btn-default-hover-border-color-dark;--highlight-background: $highlight-background-dark;--highlight-foreground: $highlight-foreground-dark;--highlight-gutter-background: $highlight-gutter-background-dark;--highlight-gutter-foreground: $highlight-gutter-foreground-dark;}img {opacity: .75;&:hover {opacity: .9;}}}
}
暗黑模式激活后,Darkmode.js 默认会将 darkmode--activated CSS 类添加到 body 标签,可以利用它覆盖暗黑模式默认的 CSS 样式。换句话说,只要将上面的 themes/next/source/css/_colors.styl 里的 CSS 样式添加到 darkmode--activated CSS 类的下面,就可以实现暗黑模式的 CSS 样式自定义,包括代码块颜色自定义切换等。
实现步骤介绍
- 第一步:创建
themes/next/source/css/_custom/darkmode.styl源文件,并将以下内容写入到文件里,code样式用于控制暗黑模式下的代码块颜色显示
.darkmode--activated{--body-bg-color: $body-bg-color-dark;--content-bg-color: $content-bg-color-dark;--card-bg-color: $card-bg-color-dark;--text-color: $text-color-dark;--blockquote-color: $blockquote-color-dark;--link-color: $link-color-dark;--link-hover-color: $link-hover-color-dark;--brand-color: $brand-color-dark;--brand-hover-color: $brand-hover-color-dark;--table-row-odd-bg-color: $table-row-odd-bg-color-dark;--table-row-hover-bg-color: $table-row-hover-bg-color-dark;--menu-item-bg-color: $menu-item-bg-color-dark;--btn-default-bg: $btn-default-bg-dark;--btn-default-color: $btn-default-color-dark;--btn-default-border-color: $btn-default-border-color-dark;--btn-default-hover-bg: $btn-default-hover-bg-dark;--btn-default-hover-color: $btn-default-hover-color-dark;--btn-default-hover-border-color: $btn-default-hover-border-color-dark;--highlight-background: $highlight-background-dark;--highlight-foreground: $highlight-foreground-dark;--highlight-gutter-background: $highlight-gutter-background-dark;--highlight-gutter-foreground: $highlight-gutter-foreground-dark;img {opacity: .75;&:hover {opacity: .9;}}code {color: #69dbdc;background: transparent;}}
若添加上述 CSS 样式后,暗黑模式的切换按钮点击无效,那么可以尝试追加以下样式来解决
button.darkmode-toggle {z-index: 9999;
}
- 第二步:在
themes/next/source/css/main.styl文件里引入上面创建的 CSS 文件即可
@import '_custom/darkmode.styl';
- 第三步:在
themes/next/layout/_scripts/vendors.njk里更改Darkmode.js的颜色配置(如下所示),其中主要设置mixColor: 'transparent'与backgroundColor: 'transparent',否则自定义的暗黑模式 CSS 样式无法达到预期的显示效果
{# Customize darkmode.js - Declaration #}
{%- if theme.darkmode_js.enable %}
{%- endif %}{# Customize darkmode.js - Invokation #}
{%- if theme.darkmode_js.enable %}
{%- endif %}
重新构建生成静态文件
Hexo 重新构建生成静态文件后,点击页面上的按钮即可切换暗黑模式
$ hexo clean$ hexo g -d
最终演示效果

常见问题
Darkmode.js 详细配置
- Darkmode Github
Chrome 无法正常显示切换按钮的图标
默认的切换按钮图标 label: '🌓' 是 Emoji 表情字符,部分浏览器(如 Chrome)可能会显示为一个方块。解决方法是访问 Chrome 网上应用商店,手动安装 Chromoji 浏览器插件,即可让 Chrome 正常显示 Emoji 表情字符。请确保可以科学上网,否则无法正常访问 Chrome 的网上应用商店。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
