现在无论是做一个网站,或是一个App,基本上你都需要考虑暗黑模式。支持暗黑模式已经成为时下的一种标准了。
我的微言码道的网站(https://taoofcoding.tech), 理所当然也要与时俱进。所以这个周末,我就花了点时间,对微言码道的网站做了一次改版,加入了暗黑模式。
从现在开始,微言码道官网正式支持普通及暗黑两种UI了,你可以自由选择与切换。

要给网站实现一个暗黑模式,或者扩大范围来说,想给你的网站添加不同的皮肤,需要的代码量极少,而且无须依赖任何第三方库,使用纯CSS是最简洁高效的。
怎么做呢,我这篇文章就简单的讲下思路及实现方式。
一个最简单高效的换肤的实现,依赖以下两个CSS特性。
CSS变量
CSS是支持变量的,基本用法是以 -- 开始进行变量的定义。
//在整个文档范围内定义一个主背景色
html {
//
--main-bg-color: brown;
}
div {
//引用了这个变量值
background-color: var(--main-bg-color);
}这就是CSS变量。
所谓网站的UI,无非就是不同的色调,文字大小而已。所以有了变量,我们就可以很轻易的把需要更换的一些点抽取成变量,进行统一定义。
这样想要换肤,只需要修改这些定义就可以了。对吧,这是很容易理解的。
但如何修改这些定义?这就涉及到CSS的另一个特性了,那就是优先级。
CSS优先级 (特指度)
在CSS规则中,同一个元素,很可能会被多个CSS匹配选中,那如何判定究竟哪一个CSS是应该被匹配到的呢。
在CSS的官方术语中,这个叫做特指度
.title {
background-colo: red;
}
#id1 {
background-color: yellow;
}
<div class="title" id="id1">究竟我是哪个背景色呢</div>比如上面这个示例,这个div同时匹配 title 以及 #id1 两个CSS定义的,那它究竟匹配哪个?
这就是CSS中特指度要解决的问题。
CSS中的特指度包括四个部分,其规则说实话有点复杂。我就不详细介绍了,有兴趣的可以参阅《CSS权威指南》以做进一步了解。
我更喜欢用更简洁明了的另一种规则来解释这种选择,就是优先级,而我在写CSS时,也只会选择编写适合这个规则的CSS语法特性。
CSS中,指向越精确的优先级越高,越粗略的优先级越低
以上面的为例, #id1这个指向更精确,因为ID是唯一的,而.title指向更粗略,因为它可能会指向多个元素。所以#id1的优先级会比.title优先级更高。
这就是我喜欢用的CSS优先级的规则。你可以参考下。
CSS变量 + CSS优先级
所以,基于CSS变量加上CSS优先级,我们现在就可以很轻易的实现换肤了。
定义不同的皮肤的CSS变量
将网站的皮肤相关的点,抽取成变量,然后根据不同的皮肤,定义不同的变量
以微言码道的实现为例
//定义默认模式下的变量值
html {
// 整体背景色
--main-color: #F8F8F8;
// 主内容范围背景色
--page-content-color: white;
// 导航栏背景色(终)
--header-bg-color:#6d9eeb;
// 导航栏背景色(起)
--header-bg-color-left: white;
// 主要文字色
--text-main: black;
// 次要文字色
--text-secondary: darkgray;
// 第三级别文字色
--text-third: lightGray;
//...
}
//定义暗黑模式下的变量,很显然,它比前面一个更精确
html[theme="dark"] {
--main-color: #9da7b0;
--page-content-color: #494949;
--header-bg-color:#666666;
--header-bg-color-left: #d9d9d9;
--text-main: white;
--text-secondary: darkgray;
--text-third: lightGray;
//...
}如上代码所示,定义了两套变量,按照前述的CSS优先级,这两个css的优先级不一样,不会同时生效。
所以,切换整个网站UI的皮肤的方式,很简单。就是在html标签上,定义theme属性的值就可以了
//它只匹配 html {} 样式定义,所以是默认主题
<html>
//... 省略内容
</html>
//它同时匹配 html {} 以及 html[theme='dark'] 两个定义,但显然html[theme='dark']的优先级更高
<html theme="dark">
//... 省略内容
</html>当然,我们一般会提供一个切换功能,我们就用JavaScript来实现就行了
const theme = "dark" // or "light"
document.documentElement.setAttribute("theme", theme);进一步,如果你想根据系统选择自动适配皮肤,那就读取系统的就好了,主流浏览器都提供了支持
//读取系统是否为暗黑模式
const systemDark = window.matchMedia("(prefers-color-scheme: dark)").matches;如果你希望记住用户选择的皮肤,就用localstorage存储就好了,非常简单。
是的,这就是全部了,整个暗黑模式的实现不依赖任何第三方框架或CSS库,使用的都是纯CSS特性。
我想没有更简单高效的实现了吧。
而且,按照这种模式,不要说实现暗黑模式,给你的网站做不同的皮肤或主题,也是非常简单容易的事了。
现在你知道该怎么做了吧。
记住,微言码道的网站是: https://taoofcoding.tech, 当初选择这个域名也是费了我一番心思的:
tao 指的是“道”,道生一,一生二,二生三,三生万物。编程也是如此,编程的道才是程序员最重要的东西,至于具体的框架也好,编程语言也好,那是术。术一定是来源于道的。一个程序员,不理解道,是不可能用好术的。coding 指的是编码tech 这个后缀,特指技术,编程当然就是技术了。微言码道只关注编程。是不是很容易记?
这是我的微言码道的最重要与核心的载体,我还在规划一个移动App,敬请期待哦。