暗夜模式实现
本质上就是通过判断某个时机来去修改样式,实现方案就分解成:时机、修改样式这两个问题了。
常见的方法有:
媒体查询
/* 系统设置浅色模式 */ @media (prefers-color-scheme: light) {} /* 系统设置深色模式 */ @media (prefers-color-scheme: dark) {}
通过媒体查询可以获取到系统当前的设定,从而直接修改对应的样式。
在支持 css 变量的浏览器环境中,更常见的做法是通过媒体查询动态地修改 root 下面的 css 变量,然后具体的组件样式使用 css 变量来作为样式值,这样可以将样式都收拢到一个地方,方便维护。
这个方法的缺点是,浅色模式和深色模式会跟着系统设置来,并没有办法由用户手动地去切换。
data set + css 属性选择器
我们可以通过元素标签上的 data set 存放一些属性,自然也可以在根元素上去定义一个 data-theme 属性,属性值可以是 light 和 dark。
在用户第一次进入页面的时候,可以通过
window.matchMedia('(prefers-color-scheme: dark)').matches
来获取系统当前的设置,为 data-theme 属性配置一个默认值,然后通过 css 属性选择器来定义 css 变量,和上面的方法一样实现深色模式。这个方法的好处是 data-theme 这个属性是可以由 js 修改的,我们可以做一个按钮或者选择器来给用户手动切换与自动跟随系统,这个也是现在许多系统都有提供的功能。同时由于有了 js 的加入,我们也可以将这个值记录在 localStorage 这种持久化存储里面,记录用户上次的使用习惯,在用户再次进入页面的时候就取出来,而不是通过媒体查询去查询了。
总结一下现在常见的方法,时机这个东西的获取有现成的媒体查询能够获取默认值,然后也可以通过 localStorage 或者 state 等地方存储状态来控制是浅色模式还是深色模式。修改样式这一块可以通过 JavaScript 动态修改,也可以通过修改 css 样式来实现,目前常见的组件库都用到了 css 变量来作为样式值,那其实就可以通过 css 的属性选择器或者 JavaScript 直接修改样式值来实现了。