主题适配夜间模式

Wanjiongming 于 2021-01-11 发布

最近 GitHub 上有人提 issues 暗黑模式 #11,说来也巧我也正打算去适配夜间模式,于是花了一晚上的时间改了下,样式基本上是照抄的 GitHub

效果

本来打算把那个猫猫也移植过来的,但是感觉放上去有点违和就算了。是否开启默认是跟随系统的,顺便做了个小彩蛋把临时开关的开关藏在了 Logo 上面

猫猫

实现方式

CSS 的媒体查询是支持检测夜间模式的,因此只需要加个 CSS 适配下就可以了

@media (prefers-color-scheme: dark) {
}

但是媒体查询有个缺点,只能被动触发,想要在页面上做个开关来控制就无法实现了。因此打算按照传统的网站换肤(切换 class,样式覆盖)的方式去实现。这时候就要通过 JS 来判断当前系统是否是夜间模式。发现可以通过window.matchMedia这个函数来判断,该函数不仅可以做媒体查询还可以监听变化

// 跟随系统
blog.setDarkTheme(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
if (window.matchMedia) {
  var media = window.matchMedia('(prefers-color-scheme: dark)')
  media.addListener(ev => (isDarkModel = blog.setDarkTheme(ev.currentTarget.matches)))
}

另外又学到了一点,可以在 link 标签中通过 media 属性来引入动态 CSS。注意页面加载阶段还是会下载的,只不过不生效,当符合媒体查询条件时会动态的生效

<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)" />

总体的适配还算简单,改改样式就好了,唯一比较麻烦的是代码高亮部分的样式。当时忘了从哪找的 Jekyll 代码高亮的样式,不过后来发现 Jekyll 使用的是 rouge 生成高亮 class,因此可以通过 rougify 来导出一些内置的主题,如rougify style base16.monokai.dark > code-dark.css

CSS 变量

通过观察 GitHub 的实现,发现他使用的是 CSS 变量来控制一些动态的颜色,又 Get 到了一个新技能 √。对于本站来说其实是不太适用的,应为最开始在写的时候样式大部分都是抄的,东拼西凑,没有一个统一的颜色规范,想要改成通过 CSS 变量来控制改动量就太大了。但是还是有必要了解下 CSS 变量的的。

通过--xxx来定义变量,通过 var 来使用变量。和 CSS 属性一样变量是会继承的,使用优先级高的变量,也就是说在html或者:root声明的变量就算是全局变量了

当然也可以通过 JS 来设置和获取 CSS 变量

/* :root 选择器就是html */
:root {
}
html {
  --background-color: white;
}
div {
  /* --background-color: pink; */
  background-color: var(--background-color, blue);
}
document.body.style.setProperty('--background-color', '#7F583F')
document.body.style.getPropertyValue('--background-color').trim()
document.body.style.removeProperty('--background-color')
document.body.style = '--background-color:#7F583F;'

参考

给网站添加暗黑模式指南

CSS 变量教程