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 颜色和度量单位等问题,包括颜色的选取方式.相对长度和绝对长度等. 一.颜色表方案 颜色的表现形式主要有 ...
随机推荐
- Python 继承和子类示例:从 Person 到 Student 的演示
继承允许我们定义一个类,该类继承另一个类的所有方法和属性.父类是被继承的类,也叫做基类.子类是从另一个类继承的类,也叫做派生类. 创建一个父类 任何类都可以成为父类,因此语法与创建任何其他类相同: 示 ...
- 对 List 列表中的数据按指定字段进行排序
/** * 对列表中的数据按指定字段进行排序.要求类必须有相关的方法返回字符串.整型.日期等值以进行比较. * * @param list 集合 * @param sortName 需要排序的字段,目 ...
- XML文件的解析--libxml库函数解释
[c语言]XML文件的解析--libxml库函数解释 2009-09-02 13:12 XML文件的解析--libxml库函数解释 libxml(一) ...
- gitlab : You won`t be able to pull or push project code via SSH until you add an SSH key to your profile(导致的问题:合并不了代码)
gitlab : You won`t be able to pull or push project code via SSH until you add an SSH key to your pro ...
- raspberry pi Pico使用MicroPython变砖后的解决方法
使用raspberry pi Pico的原因 在硬件产品(单片机)的开发中我们往往需要借助一些额外的仪器/设备进行产品的辅助测试, 假设我们需要一个IO+ADC类型辅助设备, 以往的做法是 原理图-& ...
- Vue 项目部署到GitHub Pages并同步到Gitee Pages
前言:相信很多前端开发者都拥有自己的vue项目,若想把自己的项目做成网站分享给大家看,最常用的就是利用Github提供的GitHub Pages服务和Gitee提供的Gitee Pages服务.其中, ...
- STL容器详解
详细总结STL 为什么C++比C更受人欢迎呢?除了C++ 的编译令人感到更舒适,C++的标准模板库(STL)也占了很重要的原因.当你还在用手手写快排.手写二叉堆,挑了半天挑不出毛病的时候,C++党一手 ...
- 【译】Visual Studio 2022 - 17.8 的性能改进
Visual Studio 2022 17.8版本欢迎一系列令人振奋的性能增强,包括响应式文件打开体验,改进 Razor/Blazor 的响应性,加速 F5,优化的 C++ 虚幻引擎智能感知和非 SD ...
- C#winform中使用SQLite数据库
公众号「DotNet学习交流」,分享学习DotNet的点滴. SQLite简介 SQLite是一种轻量级的关系型数据库管理系统(RDBMS),它以一个C库的形式提供.以下是SQLite数据库的一些关键 ...
- 23C新特性:True Cache的介绍
我们的文章会在微信公众号"Oracle恢复实录"和博客网站"https://www.cnblogs.com/www-htz-pw/" 同步更新 ,欢迎关注收藏, ...