首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >我用了十行代码,实现了微言码道网站的暗黑模式

我用了十行代码,实现了微言码道网站的暗黑模式

作者头像
御剑
发布2022-11-18 14:42:26
发布2022-11-18 14:42:26
5790
举报
文章被收录于专栏:微言码道微言码道

现在无论是做一个网站,或是一个App,基本上你都需要考虑暗黑模式。支持暗黑模式已经成为时下的一种标准了。

我的微言码道的网站(https://taoofcoding.tech), 理所当然也要与时俱进。所以这个周末,我就花了点时间,对微言码道的网站做了一次改版,加入了暗黑模式。

从现在开始,微言码道官网正式支持普通及暗黑两种UI了,你可以自由选择与切换。

实现思路

要给网站实现一个暗黑模式,或者扩大范围来说,想给你的网站添加不同的皮肤,需要的代码量极少,而且无须依赖任何第三方库,使用纯CSS是最简洁高效的。

怎么做呢,我这篇文章就简单的讲下思路及实现方式。

一个最简单高效的换肤的实现,依赖以下两个CSS特性。

  • • CSS变量
  • • CSS优先级

CSS变量

CSS是支持变量的,基本用法是以 -- 开始进行变量的定义。

代码语言:javascript
复制
//在整个文档范围内定义一个主背景色
html {
  //
  --main-bg-color: brown;
}


div {
  //引用了这个变量值
  background-color: var(--main-bg-color);
}

这就是CSS变量。

所谓网站的UI,无非就是不同的色调,文字大小而已。所以有了变量,我们就可以很轻易的把需要更换的一些点抽取成变量,进行统一定义。

这样想要换肤,只需要修改这些定义就可以了。对吧,这是很容易理解的。

但如何修改这些定义?这就涉及到CSS的另一个特性了,那就是优先级。

CSS优先级 (特指度)

在CSS规则中,同一个元素,很可能会被多个CSS匹配选中,那如何判定究竟哪一个CSS是应该被匹配到的呢。

在CSS的官方术语中,这个叫做特指度

代码语言:javascript
复制
.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变量

将网站的皮肤相关的点,抽取成变量,然后根据不同的皮肤,定义不同的变量

以微言码道的实现为例

代码语言:javascript
复制
//定义默认模式下的变量值
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属性的值就可以了

代码语言:javascript
复制
//它只匹配 html {} 样式定义,所以是默认主题
<html>
 //... 省略内容
</html>

//它同时匹配 html {} 以及 html[theme='dark'] 两个定义,但显然html[theme='dark']的优先级更高
<html theme="dark">
 //... 省略内容
</html>

当然,我们一般会提供一个切换功能,我们就用JavaScript来实现就行了

代码语言:javascript
复制
const theme = "dark" // or "light"
document.documentElement.setAttribute("theme", theme);

进一步,如果你想根据系统选择自动适配皮肤,那就读取系统的就好了,主流浏览器都提供了支持

代码语言:javascript
复制
//读取系统是否为暗黑模式
const systemDark = window.matchMedia("(prefers-color-scheme: dark)").matches;

如果你希望记住用户选择的皮肤,就用localstorage存储就好了,非常简单。

是的,这就是全部了,整个暗黑模式的实现不依赖任何第三方框架或CSS库,使用的都是纯CSS特性。

我想没有更简单高效的实现了吧。

而且,按照这种模式,不要说实现暗黑模式,给你的网站做不同的皮肤或主题,也是非常简单容易的事了。

现在你知道该怎么做了吧。

微言码道的网站

记住,微言码道的网站是: https://taoofcoding.tech, 当初选择这个域名也是费了我一番心思的:

  • tao 指的是“道”,道生一,一生二,二生三,三生万物。编程也是如此,编程的道才是程序员最重要的东西,至于具体的框架也好,编程语言也好,那是术。术一定是来源于道的。一个程序员,不理解道,是不可能用好术的。
  • coding 指的是编码
  • tech 这个后缀,特指技术,编程当然就是技术了。微言码道只关注编程。

是不是很容易记?

这是我的微言码道的最重要与核心的载体,我还在规划一个移动App,敬请期待哦。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微言码道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现思路
  • 实现策略
  • 微言码道的网站
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档