Stellar可控夜间模式

Posted on 2026-03-03 16:59  笔名钟意  阅读(1)  评论(0)    收藏  举报

前言

可能习惯了主题能自己改变黑夜白昼, 所以打算做访客控制的配置.
吃怕了换主题和更新主题的苦, 所以尽量抽离出来, 尽量不修改主题文件.
这篇文章也是记录本次修改, 怕下次忘记改, 修改遵循原则:

  • 尽量不修改主题文件
  • 尽量与主题样式一致
  • 尽量做到便携可移植

思路

  1. 抽离夜间样式
  2. 增加我们CSS文件优先级
  3. 网页添加主题按钮
  4. 评论主题跟随
  5. 后续优化

抽离夜间样式

查阅主题配置文件可以看到博主控制昼夜是通过style.darkmode: false # auto / always / false
来控制stylus生成整个网站main.css
再查阅主题样式代码可以看到if hexo-config('style.darkmode') == 'always'包裹的就是夜间主题代码
我们把它抽离出一个单独的ZYDark.css文件

增加我们CSS文件优先级

我的想法是通过给html标签一个ID来取得优先级, 抽离的ZYDark.css都赋予这个ID.
比如:root{--site-bg: #1c1e21;}变成#ZYDark:root{--site-bg: #1c1e21;}

网页添加主题按钮

想了很多种方案都达不到主题样式一致原则.
最后发现这里有7个位置!

就拿他来当切换按钮吧!

储存与功能实现

用户变量就扔到localStorage储存,反正不清空浏览器缓存就是永久储存.
功能实现函数操作全都是一个JS执行, 包括给html标签一个ID.

黑夜闪白优化

因为一些渲染顺序原因这个js只能放到网页靠末尾地方, 可能不是控制主题功能我还有其它功能方法, 所以结果是黑暗模式下刷新有点闪白色.
解决办法是在head引入一个提前js,即判断localStorage是黑暗就马上给html加黑色ID, 后续渲染就没问题了!!!

评论主题跟随

评论按这个思路去改吧, 加几句css的事情, 不会可以问博主.
但我用的giscus就有点麻烦, 主题没有给giscus样式是引入的, 所以我的js里面有关于giscus的方法, 不用可以删除.

2023.2.4: 很棒, 我受够了引入式的giscus不太跟随主题变化(虽然它真的很棒). 投靠waline(香).

代码

样式

提取的stellar黑夜样式,一般无需修改, 你也可以自定义

#ZYDark:root {
  --site-bg: #1c1e21;
  --card: #373d43;
  --block: #26292c;
  --block-border: #383d42;
  --block-hover: #2f3337;
  --text-p0: #fff;
  --text-p1: #ccc;
  --text-p2: #b3b3b3;
  --text-p3: #858585;
  --text-p4: #707070;
  --text-meta: #4d4d4d;
  --text-code: #ff6333;
}
@media screen and (max-width: 667px) {
  #ZYDark:root {
    --site-bg: #000;
  }
}
#ZYDark:root {
  --blur-bg: rgba(0,0,0,0.5);
}
#ZYDark .float-panel {
  --blur-bg: rgba(0,0,0,0.4);
}
#ZYDark .tag-plugin.tag {
  --theme: #ff6333;
  --theme-bg1: #3d1e14;
  --theme-bg2: #2f2522;
  --theme-border: #5c2d1f;
  --text-p0: #ffc4b3;
  --text-p1: #dfae9f;
  --text-p2: #f1997e;
}
#ZYDark .tag-plugin[color='red'] {
  --theme: #f44336;
  --theme-bg1: #3d1714;
  --theme-bg2: #2f2322;
  --theme-border: #5c231f;
  --text-p0: #ffb8b3;
  --text-p1: #dfa49f;
  --text-p2: #f1867e;
}
#ZYDark .tag-plugin[color='orange'] {
  --theme: #fa6400;
  --theme-bg1: #3d2514;
  --theme-bg2: #2f2722;
  --theme-border: #5c371f;
  --text-p0: #ffd1b3;
  --text-p1: #dfb99f;
  --text-p2: #f1ac7e;
}
#ZYDark .tag-plugin[color='yellow'] {
  --theme: #ffbd2b;
  --theme-bg1: #3d3014;
  --theme-bg2: #2f2b22;
  --theme-border: #5c491f;
  --text-p0: #ffe7b3;
  --text-p1: #dfcb9f;
  --text-p2: #f1cd7e;
}
#ZYDark .tag-plugin[color='green'] {
  --theme: #3dc550;
  --theme-bg1: #143d1a;
  --theme-bg2: #222f24;
  --theme-border: #1f5c27;
  --text-p0: #b3ffbd;
  --text-p1: #9fdfa8;
  --text-p2: #7ef18e;
}
#ZYDark .tag-plugin[color='cyan'] {
  --theme: #1bcdfc;
  --theme-bg1: #14353d;
  --theme-bg2: #222d2f;
  --theme-border: #1f4f5c;
  --text-p0: #b3efff;
  --text-p1: #9fd2df;
  --text-p2: #7ed9f1;
}
#ZYDark .tag-plugin[color='blue'] {
  --theme: #2196f3;
  --theme-bg1: #142b3d;
  --theme-bg2: #222a2f;
  --theme-border: #1f415c;
  --text-p0: #b3ddff;
  --text-p1: #9fc3df;
  --text-p2: #7ebef1;
}
#ZYDark .tag-plugin[color='purple'] {
  --theme: #9c27b0;
  --theme-bg1: #37143d;
  --theme-bg2: #2d222f;
  --theme-border: #531f5c;
  --text-p0: #f4b3ff;
  --text-p1: #d69fdf;
  --text-p2: #e07ef1;
}
#ZYDark .tag-plugin[color='light'] {
  --theme-border: #fff;
  --theme-bg1: #e0e0e0;
  --theme-bg2: #fff;
  --text-p0: #000;
  --text-p1: #111;
  --text-p2: #1f1f1f;
  --text-p3: #555;
  --text-code: #fff;
}
#ZYDark .tag-plugin[color='dark'] {
  --theme-border: #000;
  --theme-bg1: #1f1f1f;
  --theme-bg2: #111;
  --text-p0: #fff;
  --text-p1: #fff;
  --text-p2: #e0e0e0;
  --text-p3: #ddd;
  --text-code: #fff;
}
#ZYDark .tag-plugin[color='warning'],
#ZYDark .tag-plugin[color='light'] {
  --text-p0: #000;
  --text-p1: #111;
  --text-p2: #1f1f1f;
  --text-p3: #555;
  --text-code: #fff;
}
#ZYDark .social-wrap a.social:hover {
  box-shadow: none;
}

/* waline评论样式 */
#ZYDark .wl-count{
  padding: .375em;
  font-weight: bold;
  font-size: 1.25em;
  color: #fff;
}
#ZYDark .cmt-body.waline{
  --waline-white: #000;
  --waline-light-grey: #666;
  --waline-dark-grey: #999;
  /* 布局颜色 */

  --waline-color: #fff;
  --waline-bgcolor: var(--block);
  --waline-bgcolor-light: #272727;
  --waline-border-color: #333;
  --waline-disable-bgcolor: #444;
  --waline-disable-color: #272727;
  /* 特殊颜色 */
  --waline-bq-color: #272727;
  /* 其他颜色 */
  --waline-info-bgcolor: #272727;
  --waline-info-color: #666;
}
   

函数

比如我的按钮在网页左下角第5开始是: dark, light, Moss(流浪地球AI的意思), 对应是下面这个代码的567.
如果按钮按我的顺序而且是giscus评论模块则无需修改代码. 但giscus默认评论样式改成light.

2023.2.4: 离开giscus的我每晚睡的很好。如果你是giscus请使用这里面的代码。
{% link https://alist.thatcoder.cn/public/CoderSpace/Stellar/ZYDark.js
Giscus版JS %}

/**
 * 监听系统主题
 * @type {MediaQueryList}
 */
var OSTheme = window.matchMedia('(prefers-color-scheme: dark)');
OSTheme.addListener(e => {
    if (window.localStorage.getItem('ZYI_Theme_Mode') === 'Moss') {
        ThemeChange('Moss');
    }
})
/**
 * 修改博客主题
 * @param theme 亮为light,暗为dark,自动为auto
 * @constructor
 */
const ThemeChange = (theme) => {
    if (theme === 'light' || (theme === 'Moss' && !OSTheme.matches)) {
        document.querySelector("html").id = "ZYLight";
        document.querySelector("#start > aside > footer > div > a:nth-child(6)").style.filter= 'grayscale(0%)';
        document.querySelector("#start > aside > footer > div > a:nth-child(5)").style.filter= 'grayscale(100%)';
    } else {
        document.querySelector("html").id = "ZYDark";
        document.querySelector("#start > aside > footer > div > a:nth-child(5)").style.filter= 'grayscale(0%)';
        document.querySelector("#start > aside > footer > div > a:nth-child(6)").style.filter= 'grayscale(100%)';
    }
    if (theme==='Moss'){document.querySelector("#start > aside > footer > div > a:nth-child(7)").style.filter= 'grayscale(0%)';}
    else {document.querySelector("#start > aside > footer > div > a:nth-child(7)").style.filter= 'grayscale(100%)';}
    window.localStorage.setItem('ZYI_Theme_Mode', theme);
}
/**
 * 初始化博客主题
 */
switch (window.localStorage.getItem('ZYI_Theme_Mode')) {
    case 'light':
        ThemeChange('light');
        break;
    case 'dark':
        ThemeChange('dark');
        break;
    default:
        ThemeChange('Moss');
}
/**
 * 切换主题模式
 */
document.querySelector("#start > aside > footer > div > a:nth-child(5)").onclick = () => {
    ThemeChange('dark');
}
document.querySelector("#start > aside > footer > div > a:nth-child(6)").onclick = () => {
    ThemeChange('light');
}
document.querySelector("#start > aside > footer > div > a:nth-child(7)").onclick = () => {
    ThemeChange('Moss');
}

提前量

就一句js,你也可以打包成文件. 就这样写的话别漏了那个 |

# 自定义引入css,js
inject:
  head:
    - |
      <script>
        if (window.localStorage.getItem('ZYI_Theme_Mode')==='dark' || (window.localStorage.getItem('ZYI_Theme_Mode')==='Moss' && window.matchMedia('(prefers-color-scheme: dark)').matches)){
            document.querySelector("html").id = "ZYDark";
        }
      </script>

引入样式与函数

看你自定义代码文件放哪咯, 我的在根目录/source/custom/里面
if you like 你也可以挂成CDN链接引入

# 自定义引入css,js
inject:
  head:
    - <link rel="stylesheet" href="/custom/css/ZYDark.css"> # 黑夜样式
  script:
    - <script type="text/javascript" src="/custom/js/ZYDark.js"></script> # 黑夜控制

自定义博主配置

darkmodefalse意味对主题而言保持永远白昼(才有了我们的操作空间)
然后footer.social这东西我对应是567, 懒得改JS的可以前面也加四个社交按钮.

style:
  darkmode: false # auto / always / false

# 页尾
footer:
  social:
   github:
     icon: '<img src="https://upyun.thatcdn.cn/public/img/icon/github-logo2.png"/>'
     url: https://github.com/tovarsh
   music:
     icon: '<img src="https://upyun.thatcdn.cn/public/img/icon/neteasemusic-icon.png"/>'
     url: https://music.163.com/#/user/home?id=134968139
   bili:
     icon: '<img src="https://upyun.thatcdn.cn/public/img/icon/bilibili-icon.png"/>'
     url: https://space.bilibili.com/1664687779
   card:
     icon: '<img src="https://upyun.thatcdn.cn/public/img/icon/weChat.png"/>'
     url: https://muselink.cc/naive
   Moon:
     icon: '<img id="ThemeM" src="https://upyun.thatcdn.cn/public/img/icon/Moon.png"/>'
     url: javaScript:void('永夜');
   Sun:
     icon: '<img id="ThemeL" src="https://upyun.thatcdn.cn/public/img/icon/Sun.png"/>'
     url: javaScript:void('永昼');
   AI:
     icon: '<img id="ThemeAI" src="https://upyun.thatcdn.cn/public/img/icon/AI.png"/>'
     url: javaScript:void('跟随系统');

修改主题文件

waline评论才要这步, 其它评论自己看一下comments文件夹

  1. 文件路径: 根目录/themes/stellar/source/css/_plugins/comments/waline.styl
  2. 注释掉 41-64 行

结语

至此结束了, 有什么问题可以评论留言.
方案我会一直优化下去.

{% timeline %}

钟意发表了此篇文章.

修复没有giscus评论页面导致切换主题代码停止运行.

不能完美解决问题, 就把问题解决!
评论插件更换为waline.

{% endtimeline %}