DEMO
定义色板
:root {
--blue: royalblue;
--red: tomato;
--black-100: rgba(0,0,0,1);
--black-80: rgba(0,0,0,.8);
--black-60: rgba(0,0,0,.6);
--black-40: rgba(0,0,0,.4);
--black-20: rgba(0,0,0,.2);
--white-100: rgba(255,255,255,1);
--white-80: rgba(255,255,255,.8);
--white-60: rgba(255,255,255,.6);
--white-40: rgba(255,255,255,.4);
--white-20: rgba(255,255,255,.2);
}
预先定义好所有要用到的颜色,色板的颜色与主题无关,供主题取色
定义主题
.dark {
color-scheme: dark;
--bg: var(--black-100);
--text: var(--white-100);
}
.light {
color-scheme: light;
--bg: var(--white-100);
--text: var(--black-100);
}
定义了dark和light两套主题,主题内的变量是有UI语义的,变量名代表了具体UI 值是从色板取的具体颜色
主题模式实现
Theme代表了具体的主题定义,而Theme Mode是UI的主题模式 是供用户手动选择的(默认System),我们要根据UI的模式来动态切换主题定义,通常有3种模式 system light dark
System 跟随系统模式
@media(prefers-color-scheme: dark) {
:root:not(.light):not(.dark) {
--bg: var(--black-100);
--text: var(--white-100);
}
}
@media(prefers-color-scheme: light) {
:root:not(.light):not(.dark) {
--bg: var(--white-100);
--text: var(--black-100);
}
}
媒体查询自动响应系统主题来修改主题变量,代码完全是和.dark .light重复的,因为我是用纯css举例,实际开发中用scss less等工具能用@mixin复用代码
Dark、Light 亮色暗色模式
这一步就要用🤏🏻js代码来实现,只需要切换html的class name就行,亮色.light 暗色.dark
const system = document.getElementById('system')
const light = document.getElementById('light')
const dark = document.getElementById('dark')
const root = document.documentElement
system.onclick = ()=>{
root.classList.remove('light', 'dark')
}
light.onclick = ()=>{
root.classList.remove('dark')
root.classList.add('light')
}
dark.onclick = ()=>{
root.classList.remove('light')
root.classList.add('dark')
}
持久化
用户选择模式后 下次今天要记忆上次的模式,这就需要持久化,很简单 只需要把theme mode保存到localstrage里,然后每次打开页面读取一下 然后设置模式 就可以了,具体代码不演示了。