DarkMode(2):深色模式解决方案——css颜色变量实现Dark Mode
暗黑模式实现,最初的设计,就是参考之前的主题模式。所谓多套主题/配色/皮肤,就是我们很常见的换肤功能。换肤简单的实现就是更换 css实现不同样式呈现不同肤色。
之前做不同颜色的皮肤,暗黑模式可以单做其中的一种黑色暗黑主题。
通用的方法,就是less、sass、post-css,把颜色抽离出变量。然后打包输出不同的样式,即:
CSS预处理直接生成多套主题样式
利用Less,stylus 或 sass 的变量代替颜色值
配置多个主题颜色配置
利用grunt/gulp/webpack等工具输出多套主题样式
页面加载后,根据用户需求加载不同的样式列表
推荐阅读《webpack 换肤功能多主题/配色样式打包解决方案》,配置文件:
https://github.com/hiyangguo/webpack-mutiple-theme-bundle-css-demo/blob/master/webpack.config.js
这里是以less 为例,sass 配置,稍微修改即可,这里就不做赘述了,google应该都可以搜索得到,推荐这篇也是顺手搜的
这种方式在bootstrap时代就流行开来,那时候还用过php编译less,以及java编译:java -jar js.jar less-rhino-1.4.0.js listing3.less > listing3.css
webpack loader modifyVars 生成多套样式
webpack 本身并不具备打包 less 文件的功能,最终实现该部分功能的是 less-loader,该加载器把 less 转为 CSS,在 webpack 中每个文件或模块都是有效的 JS 模块,因此我们还需要 css-loader 将CSS样式文件转换为变成 JS 模块。
这时我们已经有了生成的 dist/style.js,在这个模块中只是将样式导出为字符串并存放于数组中,我们需要 style-loader 将该数组转换成 style 标签。
less-loader 可以帮忙我们实现主体定制,通过一下这两个配置,我们就可以把部分样式抽出变量,通过不同的变量组合成不同的主题:
globalVars:相当于给每个 less 文件顶部增加一行 @VariableName: xx;
modifyVars:相当于给每个 less 文件底部增加一行变量 @variable:xx;
比如ant-design定制主题,官方demo:https://ant.design/docs/react/customize-theme-cn
其实这个和第一种方法差不多,目前facebook youtube 等,都是采用css 变量来实现
媒体查询与css变量实现
现在可以利用
CSS 的媒体查询方法:prefers-color-scheme
方法还处于 W3C 草案规范:https://caniuse.com/?search=prefers-color-scheme
CSS 变量: CSS variables、CSS custom properties
CSS 变量除了 IE,其余各大浏览器都支持的比较好:https://caniuse.com/?search=variables
二者配合就可以实现页面主题跟随系统自动切换深浅模式 。
CSS 的媒体查询
prefers-color-scheme 是一种用于检测用户是否有将系统的主题色设置为亮色或者暗色的 CSS 媒体特性。 利用其设置不同主题模式下的 CSS 样式,浏览器会自动根据当前系统主题加载对应的 CSS 样式。light 适配浅色主题,dark 适配深色主题,no-preference 表示获取不到主题时的适配方案。
CSS
@media (prefers-color-scheme: light) {
.article {
background:#fff;
color: #000;
}
}
@media (prefers-color-scheme: dark) {
.article {
background:#000;
color: white;
}
}
@media (prefers-color-scheme: no-preference) {
.article {
background:#fff;
color: #000;
}
}
Link 标签
<link href="./common.css" rel="stylesheet" type="text/css" />
<link href="./light-mode-theme.css" rel="stylesheet" type="text/css" />
<link href="./dark-mode-theme.css" rel="stylesheet" type="text/css" media="(prefers-color-scheme: dark)" />
一般推荐使用link标签解决
CSS 变量 + 媒体查询
window.matchMedia (https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia) 方法可以用来查询 指定的媒体查询字符串解析后的结果。 结合 CSS 变量和 matchMedia 的查询结果,设置对应的 CSS 主题颜色。该方法更灵活,可以单独抽离主题色进行适配。
CSS 变量的作用域与 CSS 的"层叠"规则一致,优先级最高的声明生效。所以当 body 上存在 "dark" 类名时,:root .dark 会生效,否则 :root 生效。
.article {
color: var(--text-color, #eee);
background: var(--text-background, #fff);
}
:root {
--text-color: #000;
--text-background: #fff;
}
:root .dark {
--text-color: #fff;
--text-background: #000;
}
使用 matchMedia 匹配主题媒体,深色模式匹配 (prefers-color-scheme: dark) ,浅色模式匹配 (prefers-color-scheme: light) 。
监听主题模式,深色模式时为 body 添加类名 dark,根据 CSS 变量的响应式布局特点,自动生效 dark 类名下的 CSS。
const darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');
// 判断是否匹配深色模式
if (darkMode && darkMode.matches) {
document.body.classList.add('dark');
}
// 监听主题切换事件
darkMode && darkMode.addEventListener('change', e => {
if (e.matches) {
document.body.classList.add('dark');
} else {
document.body.classList.remove('dark');
}
});
那么,针对不支持 CSS 变量的 IE 浏览器怎么办呢?不做兼容性处理的话那页面可能就是一团糟了。所以我们需要针对不兼容的浏览器做一些兜底处理,这里我们可以在 webpack 等构建工具中借助 post-css 的 postcss-css-variables (https://www.npmjs.com/package/postcss-css-variables) 插件来自动解析 CSS 变量对应的色值,并在原始 CSS 定义之上添加一条新的 CSS 样式,做到对不支持 CSS 变量浏览器的兼容。
// 根目录 postcss.config.js
module.exports = {
plugins: {
"postcss-css-variables": {
preserve: true, // 保留 var() 定义
preserveInjectedVariables: false, // 去除其他模块的重复变量
variables: require("./page.json"), // CSS 变量,可以支持多个
}
}
};
现在的 Web、App 项目大都引用第三方开源组件库,组件库一般会使用 Sass、Less 等 CSS 预处理器定义颜色变量作为组件的基础色值,并单独抽离为配置文件。所以,项目使用组件库时可以根据修改基础色值来自定义主题。那么针对项目的 深色模式适配方案也一样,主要分为三步:
组件库深浅色主题 适配
项目中 深浅色的 颜色适配
完成 CSS 变量到页面的注入
上面的都是 利用 变量,去控制样式。
sass变量与css变量处理
$var-element:'--';
// sass variable map
$colors: (
color-black: #FFBB00
); // loop over each name, color
:root {
// each item in color map
@each $name, $color in $colors {
#{$var-element}#{$name}: #{$color};
}
}
参考文章:
深色模式适配指南 https://www.zoo.team/article/dark-theme
转载本站文章《DarkMode(2):深色模式解决方案——css颜色变量实现Dark Mode》,
请注明出处:https://www.zhoulujun.cn/html/webfront/style/darkMode/8558.html
DarkMode(2):深色模式解决方案——css颜色变量实现Dark Mode的更多相关文章
- CSS颜色模式转换器的实现
前面的话 在CSS中,颜色的表示方式主要包括关键字.16进制.RGB模式.RGBA模式.HSL模式.HSLA模式.关于颜色模式的详细信息移步至此.本文就16进制.RGB模式及HSL模式的互相转换进行实 ...
- 一行代码,让 VS Code 内置 PDF 阅读器变成深色模式
使用 CSS/JS 简单实现 PDF 深色模式.
- iOS 深色模式适配
要求:iOS13.0以上 重点:需要所有界面进行适配,工作量巨大,需要从项目开始就进行适配:H5界面无法进行适配 实现方式:System Colors(常用).Semantic Colors(常用). ...
- 【CSS进阶】CSS 颜色体系详解
说到 CSS 颜色,相比大家都不会陌生,本文是我个人对 CSS 颜色体系的一个系统总结与学习,分享给大家. 先用一张图直观的感受一下与 CSS 颜色相关大概覆盖了哪些内容. 接下来的行文内容大概会按照 ...
- 代码自动补全插件CodeMix全新发布CI 2019.7.15|改进CSS颜色辅助
CodeMix是Eclipse的一款插件,它解锁了VS Code和Code OSS附加扩展的各种技术,支持各种语言. 作为Eclipse开发人员,您再也不必觉得自己已被排除在朋友使用Visual St ...
- css - 原生变量及使用函数 var()
零.序言 前两天在逛 blog 的时候看见一些内联样式新奇的写法时很纳闷,虽然说不上多么熟练,但是从来没见过 --color: brown 这样的写法,百度一番之后仍然没啥头绪,今天偶然看到一篇文章 ...
- Android QMUI实战:实现APP换肤功能,并自动适配手机深色模式
Android换肤功能已不是什么新鲜事了,市面上有很多第三方的换肤库和实现方案. 之所以选择腾讯的QMUI库来演示APP的换肤功能,主要原因: 1.换肤功能的实现过程较简单.容易理解: 2.能轻松适配 ...
- windows自动切换深色模式(夜晚模式)
img { width: 30vw } windows系统上怎么根据日出日落时间判断切换为深色模式或浅色模式呢? windows系统自带了一个叫做"任务计划程序"的软件.可以通过& ...
- CSS颜色代码
颜色值 CSS 颜色使用组合了红绿蓝颜色值 (RGB) 的十六进制 (hex) 表示法进行定义.对光源进行设置的最低值可以是 0(十六进制 00).最高值是 255(十六进制 FF).从 0 到 25 ...
- 第 14 章 CSS 颜色与度量单位
学习要点: 1.颜色表方案 2.度量单位 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 颜色和度量单位等问题,包括颜色的选取方式.相对长度和绝对长度等. 一.颜色表方案 颜色的表现形式主要有 ...
随机推荐
- 在不知带头节点地址的情况下删除和插入一个p指针指向的节点总结
在不知带头节点地址的情况下删除和插入一个p指针指向的节点总结 (p指向的不是第一个,也不是最后一个)A->B->C *p->B 插入(在p结点之前插入q) 解析: 直接往p前插入q, ...
- C++ 入门防爆零教程(上册)
## C++ 入门防爆零教程(上册) ###### C++ Introductory Explosion Proof Zero Tutorial(Volume $1$) 编写者:美公鸡(洛谷账号:b ...
- HelloGitHub 社区动态,开启新的篇章!
今天这篇文章是 HelloGitHub 社区动态的第一篇文章,所以我想多说两句,聊聊为啥开启这个系列. 我是 2016 年创建的 HelloGitHub,它从最初的一份分享开源项目的月刊,现如今已经成 ...
- 关于Spring i18n国际化 报错No message found under code * for locale 'zh_CN'.的解决方案
第一步 创建资源文件 国际化文件命名格式:基本名称 _ 语言 _ 国家.properties 这里我建了两个配置文件,一个是zh_CN中文的,一个是en_GB英文的,然后在里面随便写点测试文本语句 第 ...
- 普冉PY32系列(十) 基于PY32F002A的6+1通道遥控小车I - 综述篇
目录 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境 普冉PY32系列(三) P ...
- 【uniapp】学习笔记day03 | 页面制作【外包杯】
一.开发层级结构介绍 page.json 对uniapp进行全局配置,决定页面文件的路径.窗口样式.原生的导航栏.底部的原生tabbbar manifest.json 应用的配置文件,指定应用的名称. ...
- Spring Framework系统架构
- MybatisPlus高级特性之ActiveRecord模式
1.是什么? ActiveRecord是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表:而模型类的一个实例对应表中的一行记录.ActiveRecord 一直广受解释型动态语言 ( PHP ...
- bash shell笔记整理——ls命令
语法: ls [选项] [文件 或 目录] 选项 使用说明 –a 显示指定目录下的所有文件,包括隐藏文件. -A 显示除了.和..的外的所有文件. -l 显示详细的文件信息. -d 如果是目录,只显示 ...
- PersistenceException、ReflectionException、IllegalArgumentException、wrapException持久性异常 反射异常 非法参数异常 包装异常
PersistenceException.ReflectionException.IllegalArgumentException.wrapException wrapException 持久性异常 ...