prefers-color-scheme
是CSS
媒体特性【@media】用于检测用户是否有将操作系统的主题色设置为亮色【light】或者暗色【dark】。
当前prefers-color-scheme
新特性支持各大主流电脑(window
和IOS
系统,Linux
系统可以用第三方工具)端浏览器谷歌、火狐等,包括手机端的安卓和苹果,足以说明prefers-color-scheme
属性已经稳定成熟,可以用于生产环境了。
prefers-color-scheme
的使用也很简单,直接需要在全局css
文件中添加以下代码
:root {
color-scheme: light dark;
}
js
可以通过window.matchMedia()
来监听系统主题。
const scheme = window.matchMedia("(prefers-color-scheme: dark)");
if (scheme.matches) {
console.log("深色模式");
} else {
console.log("浅色模式");
}
除了自动跟随系统外,也可以手动切换。不过需要结合css
变量,详情请看第四点。
优点:
缺点:
通过改变link
的href
。
优点
缺点
类似第二种,不过为了解决反复加载样式文件问题采用提前将样式全部引入的方式,在需要切换主题的时候将指定的根元素类名更换,相当于直接做了样式覆盖,在该类名下的各个样式就统一地更换了
.light-scheme {
background: #fff;
}
.dark-scheme {
background: #1b1b1b;
}
function change(scheme) {
const content = document.getElementsByTagName("body")[0];
content.setAttribute("class", scheme);
}
优点:
缺点:
大体思路跟方案 2 相似,依然是提前将样式文件载入,切换时将指定的根元素类名更换。不过这里相对灵活的是,默认在根作用域下定义好 CSS
变量,只需要在不同的主题下更改 CSS
变量对应的取值即可。
:root {
--color-background: #1b1b1b;
--color-text-default: #0b1016;
--white-color-background: #fff;
}
.light-scheme {
background: var(--white-color-background);
color: var(--color-text-default);
}
.dark-scheme {
background: var(--color-background);
color: white;
}
let flag = true;
const content = document.getElementsByTagName("body")[0];
const but = document.getElementsByTagName("button")[0];
but.onclick = function () {
flag = !flag;
if (flag) {
content.setAttribute("class", "light-scheme");
} else {
content.setAttribute("class", "dark-scheme");
}
};
优点:
var()
绑定变量即可,不存在优先级问题CSS
变量即可,在 var()
绑定样式变量的地方就会自动更换缺点:
前面提到css
变量还可以结合prefers-color-scheme
一起使用实现跟随系统的自定义深浅主题样式。
:root {
--color-background: #1b1b1b;
--color-text-default: #0b1016;
--white-color-background: #fff;
}
/* 监听操作系统主题模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: var(--color-background);
}
}
@media (prefers-color-scheme: light) {
body {
background-color: var(--white-color-background);
}
}
适合自定义颜色背景
只需在全局中设置好预设的全局 CSS
变量样式,无需单独为每一个主题类名下重新设定 CSS
变量值,因为主题是由用户动态决定。
定义一个工具类方法,用于修改指定的 CSS
变量值,调用的是 CSSStyleDeclaration.setProperty
export const setCssVar = (
prop: string,
val: any,
dom = document.documentElement
) => {
dom.style.setProperty(prop, val);
};
在样式发生改变时调用此方法即可
setCssVar("--theme-color", color);
优点:
Vue3
的新特性 v-bind
是一致的,只不过此方案只在:root
上动态更改 CSS
变量而 Vue3
中会将 CSS
变量绑定到任何依赖该变量的节点上。:root
上动态更改 CSS
变量值即可,不存在优先级问题缺点:
<script setup>
// 这里可以是原始对象值,也可以是ref()或reactive()包裹的值,根据具体需求而定
const theme = {
color: "red",
};
script>
<template>
<p>hellop>
template>
<style scoped>
p {
color: v-bind("theme.color");
}
style>
Vue3
中在 style
样式通过 v-bind()
绑定变量的原理其实就是给元素绑定 CSS 变量,在绑定的数据更新时调用 CSSStyleDeclaration.setProperty
更新 CSS
变量值。