部分转自:布依前端和前端侦探
prefers-color-scheme
prefers-color-scheme这个新的css特性,想必大家并不陌生,写文章的目的就是分享给大家怎么正确用好它以及提升网站用户体验。
prefers-color-scheme是CSS 媒体特性【@media】用于检测用户是否有将操作系统的主题色设置为亮色【light】或者暗色【dark】,这俩个也是prefers-color-scheme重要属性。W3C 在 2020 年 7 月 31日首次提到css的prefers-color-scheme新特性。原始 Wiki 贡献者有:RainSlide、 ZZES_REN 、urusai-me和 SimGenius。
当前prefers-color-scheme新特性支持各大主流电脑【window和IOS系统,Linux系统可以用第三方工具】端浏览器谷歌、火狐等,包括手机端的安卓和苹果,足以说明prefers-color-scheme属性已经稳定成熟,可以用于生产环境了。
如何正确使用prefers-color-scheme属性呢?答:需要在全局css文件内部写入下面代码即可,用于监听系统主题变化结果:
:root {
--color-background: #1b1b1b;
--white-color-background: #fff;
color-scheme: light dark;
}
/* 监听操作系统主题模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: var(--color-background);
}
}
@media (prefers-color-scheme: light) {
body {
background-color: var(--white-color-background);
}
}
当操作系统电脑端或者手机操作系统主题颜色变化时就能监听到主题,然后就会按照你预期设置的颜色进行渲染主题色。比如这里的body暗色主题是background-color: var(--color-background),亮色主题是background-color: var(--white-color-background);
提示::root表示根元素,拥有更高的优先级,这里可以设置全局样式变量,通过css的var方法来获取对应变量且获得相应的样式。
那么除了媒体监听主题变化,能不能自定义主题呢?答:能,可以通过js来操作操作,实现自由切换主题颜色,具体细节请往下看。
这里布衣前端写了一个手动切换网站主题的html完整示例代码,看完代码不明白的请留言哈,感谢大家支持。
colorScheme.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>系统的主题色设置为亮色或者暗色</title>
<style lang="css">
/* 整个页面配置为使用用户的配色方案首选项 */
/* 根元素,优先级最高,与html选择器相同 */
:root {
--color-background: #1b1b1b;
--color-border: #cacfd5;
--color-text-default: #0b1016;
--color-base: #f4f5f6;
--color-accent: #ba0d37;
--white-color-background: #fff;
color-scheme: light dark;
}
* {
margin: 0;
padding: 0;
}
body {
text-align: center;
height: 100vh;
}
.light-scheme {
background: var(--white-color-background);
color: var(--color-text-default);
}
.dark-scheme {
background: var(--color-background);
color: white;
}
h2 {
margin: 50px auto;
color: var(--color-accent)
}
/* 监听操作系统主题模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: var(--color-background);
}
}
@media (prefers-color-scheme: light) {
body {
background-color: var(--white-color-background);
}
}
.tab-type {
display: flex;
justify-content: center;
padding-top: 30px;
}
.tab-type > li {
cursor: pointer;
color: #fff;
background-color: darkred;
border-radius: 12px;
padding: 5px;
margin: 0px 20px;
max-width: 300px;
}
</style>
</head>
<body>
<div class="content" id="content">
<ul class="tab-type">
<li id="light">浅色主题</li>
<li id="dark">暗色主题</li>
</ul>
<h2>微信公众号:[布依前端],布衣前端,专注于前端知识分享的up</h2>
<div class="scheme-tip"></div>
</div>
<script>
// 手动修改主题颜色
const light = document.getElementById('light')
const dark = document.getElementById('dark')
const content = document.getElementsByTagName('body')[0]
const tipText = document.getElementsByClassName('scheme-tip')[0]
let lightTip = '当前自定义主题:light亮色', darkTip = '当前自定义主题:dark暗色'
light.onclick = function (params) {
content.setAttribute('class', 'light-scheme')
tipText.innerHTML = lightTip
}
dark.onclick = function (params) {
content.setAttribute('class', 'dark-scheme')
tipText.innerHTML = darkTip
}
// js 监听系统主题模式
const scheme = window.matchMedia('(prefers-color-scheme: dark)')
if (scheme.matches) {
// 深色模式业务处理代码
console.log('深色模式');
tipText.innerHTML = darkTip
} else {
// 浅色模式业务处理代码
console.log('浅色模式');
tipText.innerHTML = lightTip
}
</script>
</body>
</html>
把上面完整代码复制粘贴放到一个html文件内,双击打开到浏览器。此时的默认效果是【亮色】主题:
dark暗色效果:
light亮色效果:
作用关键代码如下
/*系统亮色主题时修改body背景色*/
@media (prefers-color-scheme: light) {
body {
background-color: var(--white-color-background);
}
}
当设置windows系统主题为【暗】
再去刷新浏览页面,此时页面效果是【暗色】主题,原因:当window10设置【暗色】主题后,css的prefers-color-scheme属性通过@media媒体监听到变化后,触发了css媒体事件,执行样式渲染,这个样式就是根据开发者设置的主题样式来渲染的
作用关键代码如下
/*系统暗色主题时修改body背景色*/
@media (prefers-color-scheme: dark) {
body {
background-color: var(--color-background);
}
}
当网站不满足系统默认主题,还想提供用户自己切换主题的功能,代码中有两个按钮,【浅色主题】和【暗色主题】就是干这件事情的。用户可以随意切换,具体切换代码可以到js部分查看。
除了css媒体能监听操作系统主题变化,js也能监听的,当监听到后可以增强js业务逻辑,比如设置某个主题下布局变化、语音播报当前模式等等和其他业务处理逻辑,需要设置页面加载后添加如下代码即可:
// js 监听系统主题模式
const scheme = window.matchMedia('(prefers-color-scheme: dark)')
if (scheme.matches) {
// 深色模式业务处理代码
console.log('深色模式');
tipText.innerHTML = darkTip
} else {
// 浅色模式业务处理代码
console.log('浅色模式');
tipText.innerHTML = lightTip
}
当监听到主题变化时就可以编写其他业务逻辑了。学完了就去给自己的项目增加主题切换体验一哈prefers-color-scheme属性神奇之处吧。
总结prefers-color-scheme监听方式:
css里通过@media监听
js里面通过matchMedia监听
两种方式都能监听到操作系统主题变化后的值
color-scheme 和夜间模式
一、什么是 color-scheme?
color-scheme顾名思义,即为“配色方案”,在系统中指的是“白天模式”和“夜间模式”。使用这个属性可以轻松的更改浏览器的默认配色方案,语法如下
color-scheme: normal;
color-scheme: light;
color-scheme: dark;
color-scheme: light dark;
几个关键词如下
normal:表示元素未指定任何配色方案,因此应使用浏览器的默认配色方案呈现。
light:表示可以使用操作系统亮色配色方案渲染元素。
dark:表示可以使用操作系统深色配色方案渲染元素。
下面来看一个简单的例子
<h2>前端侦探</h2>
<button>关注我</button>
在无任何CSS的情况下,效果如下
现在在根元素上添加color-scheme
属性
:root{
color-scheme: light dark
}
这里设置两个值,表示可选的配色方案,由系统来决定。
官方文档上虽然说是优先选择,实测两种顺序没有区别,有知道的小伙伴可以留言指点
效果如下
二、color-scheme 的作用范围
通过上面的例子看着好像很强大,是不是可以一键生成“深色”模式了?其实不然,color-scheme
的作用范围很有限,包括表单控件、滚动条和 CSS 系统颜色的使用值
1. 表单元素
先看表单元素,就拿 checkbox
来说吧
<input type="checkbox">
假设现在我们需要做一个深色模式的主题,手动将页面背景设置为黑色
body[dark]{
background: #000
}
是不是感觉到未勾选状态有点太过刺眼了呢?
这时,就可以用到color-scheme
了,可以将表单元素以深色模式渲染
body[dark]{
background: #000;
color-scheme: dark
}
这样是不是柔和多了?这里选中的主题色貌似也发生了变换,这个是浏览器为了方便夜间浏览默认设置的,如果你不希望这个选中颜色,可以用accent-color
来覆盖
body{
accent-color: #0175ff
}
效果如下
accent-color
可以更改表单元素的默认颜色,有兴趣的可以参考张鑫旭的这篇文章 CSS accent-color属性简介
下面是其他表单元素的深色模式
HTML代码:
<ul id="ul">
<li>复选框:<input type="checkbox" checked></li>
<li>单选框<input type="radio" checked></li>
<li>范围选择框:<input type="range"></li>
<li>进度条:<progress value="0.5"></li>
</ul>
选择颜色:<input type="color" id="color" is="ui-color">
JS代码:
color.addEventListener('input', function () {
ul.style.accentColor = this.value;
});