Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >DarkMode(2):深色模式解决方案——css颜色变量实现Dark Mode

DarkMode(2):深色模式解决方案——css颜色变量实现Dark Mode

原创
作者头像
周陆军
发布于 2020-12-11 14:33:16
发布于 2020-12-11 14:33:16
3.6K00
代码可运行
举报
文章被收录于专栏:前端架构前端架构
运行总次数:0
代码可运行

暗黑模式实现,最初的设计,就是参考之前的主题模式。所谓多套主题/配色/皮肤,就是我们很常见的换肤功能。换肤简单的实现就是更换 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 是一种用于检测用户是否有将系统的主题色设置为亮色或者暗色的 CSS 媒体特性。 利用其设置不同主题模式下的 CSS 样式,浏览器会自动根据当前系统主题加载对应的 CSS 样式。light 适配浅色主题,dark 适配深色主题,no-preference 表示获取不到主题时的适配方案。

CSS

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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 标签

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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 生效。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.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。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 变量浏览器的兼容。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 根目录 postcss.config.js 
module.exports = { 
  plugins: { 
    "postcss-css-variables": { 
      preserve: true, // 保留 var() 定义 
      preserveInjectedVariables: false, // 去除其他模块的重复变量 
      variables: require("./page.json"), // CSS 变量,可以支持多个 
    } 
  } 
};

现在的 Web、App 项目大都引用第三方开源组件库,组件库一般会使用 Sass、Less 等 CSS 预处理器定义颜色变量作为组件的基础色值,并单独抽离为配置文件。所以,项目使用组件库时可以根据修改基础色值来自定义主题。那么针对项目的 深色模式适配方案也一样,主要分为三步:

  1. 组件库深浅色主题 适配
  2. 项目中 深浅色的 颜色适配
  3. 完成 CSS 变量到页面的注入

上面的都是 利用 变量,去控制样式。

sass变量与css变量处理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深色模式适配指南
随着 iOS 13 的发布,深色模式(Dark Mode)越来越多地出现在大众的视野中,支持深色模式已经成为现代移动应用和网站的一个潮流,前段时间更是因为微信的适配再度引起热议。深色模式不仅可以大幅减少电量的消耗,减弱强光对比,还能提供更好的可视性和沉浸感。
政采云前端团队
2020/08/18
2.9K0
深色模式适配指南
一步到位:三行CSS代码轻松实现全网站暗黑模式
在另一篇博文中,Mads Stoumann详细介绍了如何使用SVG和CSS重新创建Apple的暗黑模式图标。这证明了他在此领域的深厚技术和创新能力。
前端小智@大迁世界
2023/05/23
1.9K0
一步到位:三行CSS代码轻松实现全网站暗黑模式
网站如何适配暗色模式并实现手动、自动切换
那么,我们自己的网站如何适配暗色/亮色模式呢?首先说一下最基础的媒体查询,然后带大家了解一下我的适配方案(纯JS、CSS和HTML的前端操作)。
Mintimate
2021/02/01
9.2K0
网站如何适配暗色模式并实现手动、自动切换
网页主题自动适配:网页跟随系统自动切换主题
方式3:使用类名切换,通过对顶层节点设置不同的类名,然后定义不同类名的CSS样式,切换主题时修改类名即可
老K博客
2024/06/20
2920
为你的网页添加深色模式[每日前端夜话0x48]
CSS 规范一直在不断发展。尽管在 CSS 新功能的实现很复杂,但是 CSS 工作组还是决定要把简化版作为新元素添加到规范中。然后由浏览器来实现这些新元素,浏览器自行决定以哪种顺序去实现它们,这就是为什么现在对新功能的支持不匹配的原因。虽然这可能会令人讨厌,但实际上完成了规范的浏览器要好得多。
疯狂的技术宅
2019/04/23
1.7K0
为你的网页添加深色模式[每日前端夜话0x48]
H5 项目如何适配暗黑模式
如果系统设置了深色模式,H5页面不做相应的处理,会出现背景色冲突、深色文字显示异常,深色图标显示异常等一些显示上的问题。
@超人
2021/07/05
2.8K0
聊聊 React 组件库的技术选型与设计
最近在业务中开发了一套定制化的 C 端组件库,在这个过程中遇到了一些组件库技术选型和设计的问题,在参考公司内外的多个组件库后确定了最终的方案。本文希望通过向读者介绍技术选型的过程中的方案比较和组件库设计中的考量,让读者在组件库的技术选型和设计上有所启发。
前端迷
2021/03/18
2K0
聊聊 React 组件库的技术选型与设计
【Web技术】623- 简单好用的前端深色模式/主题化开发方案
深色模式(Dark Mode)在iOS13 引入该特性后各大应用和网站都开始支持了深色模式。在这之前,深色模式更常见于程序IDE开发界面和视频网站界面。前者通过降低屏幕亮度,使得使用人员长时间盯着屏幕眼睛没有那么疲惫;后者通过深色模式来降噪,从而突出主体内容部分。快速开发一个深色模式难吗?在支持css自定义属性(又称css变量,css variables)的现代浏览器里,可以说是相当的容易。甚至可以在运行时实时新增主题,摆脱传统css主题文件加载模式下的主题需要预编译内置不能随时修改的弊端。下面我们来看一下如何使用css自定义属性来完成深色模式和主题化的开发。
pingan8787
2020/06/18
2.2K0
【Web技术】623- 简单好用的前端深色模式/主题化开发方案
使用 React hooks 监听系统的暗黑模式
苹果的“暗黑模式”带来了全然一新的外观,它能使您的眼睛放松,并有助于您专心工作。暗黑模式使用一种较深的配色方案,这种配色作用于整个系统,现在大部分网站也加入了暗黑模式,包括 Tailwindcss、antd design 等都支持了暗黑模式,因此我们的网站也要适配系统皮肤。
狂奔滴小马
2022/03/30
1.1K0
使用 React hooks 监听系统的暗黑模式
一个深色模式的简单 CSS 技巧 | Linux 中国
你可能已经熟悉 媒体查询(media query)了。它们被广泛地用于使网站具有响应性。width 和 height 属性包含视区的尺寸。然后,你可以使用 CSS 在不同的尺寸下呈现不同的布局。
用户1880875
2021/11/08
7700
Dark Mode 实践踩坑记录
只能说,实现 Dark Mode 的尽头是手写。 手机 QQ 最近火急火燎地整改,暗黑模式的支持就是其中的一个整改项。由于腾讯课堂在手机 QQ 有一个常驻入口,因此我们也要按照它们的要求实现真正意义上的 dark mode 支持 (而不是目前手机 QQ 强制给加的一层灰色蒙层)。 大学时候有个项目也是自己设计和实现的 dark mode 支持,当时是手写的,依稀记得后面从哪些文章里看到说可以一行代码实现暗黑模式云云,于是企图在这次实践过程中应用下这些奇技淫巧,然而经过一天的实践,我发现这些方法有绕不过的坑,
用户1097444
2022/06/29
5850
Dark Mode 实践踩坑记录
使用 PostCSS 插件让你的网站支持暗黑模式
最近公司需要给多个 webapp(大概20+)加上多皮肤的功能,原先默认是白色皮肤,我们先从暗黑模式入手,从而逐渐实现多皮肤功能。本篇记录下实现思路。
狂奔滴小马
2021/11/15
8810
使用 PostCSS 插件让你的网站支持暗黑模式
让你的网页支持苹果的 黑暗模式(深色Dark模式)
在未修复前,深色模式看的话就是一片空白,因为深色模式的字体是白色,同时给了一个 background-color:#f5f5f5 样式所导致
骤雨重山
2022/01/17
9140
现代 CSS 解决方案:accent-color 强调色
accent-color 是从 Chrome 93 开始被得到支持的一个不算太新属性。之前一直没有好好介绍一下这个属性。直到最近在给一些系统整体切换主题色的时候,更深入的了解了一下这个属性。
Sb_Coco
2024/02/28
1570
现代 CSS 解决方案:accent-color 强调色
Nuxt3在使用Tailwindcss情况下,如何优雅实现深色模式切换?
随着前端更新,网站设计中,深色模式也成为了一种备受欢迎的设计趋势。可以帮助用户减少眼睛的负担,同时也更加适合在光线较暗的环境下使用。
Mintimate
2023/07/31
2.1K0
Nuxt3在使用Tailwindcss情况下,如何优雅实现深色模式切换?
现代 CSS 解决方案:accent-color 强调色
accent-color 是从 Chrome 93 开始被得到支持的一个不算太新属性。之前一直没有好好介绍一下这个属性。直到最近在给一些系统整体切换主题色的时候,更深入的了解了一下这个属性。
winty
2024/04/15
1610
现代 CSS 解决方案:accent-color 强调色
如何让你的网站支持苹果系列的深色Dark模式
我也是直接换上了 iPad 的深色模式,mbp 使用正常的浅色模式,访问自己网站的时候发现一个问题,就是下面这个引用样式有些问题
沈唁
2019/12/09
9270
前端样式那些事
CSS不仅仅是一门科学,而是一门艺术。 您可以了解选择器的每种组合,并且可以成为每种样式属性的专家,但是仍然无法根据需要布置和样式化网站。
饼干_
2022/09/19
3180
实现用户自定义主题深浅模式浏览站点
如今大部的网站都实现了深浅主题2种不同模式的配色,比如说程序员大多喜欢深色模式,或许是需要长时间使用电脑,该模式能够一定程度上保护视力。从表面现象上来看,实现这一功能需要 CSS 和 JavaScript 两者搭配着一起使用,但当深入以后发现有些没料想的事情,且听我慢慢叙说。
凡梦星尘
2024/11/20
900
实现用户自定义主题深浅模式浏览站点
js检测夜晚(dark)模式
使用CSS,我们可以使用 preferreds-color-scheme 媒体查询来检测暗模式。
IT工作者
2022/01/15
2.8K0
推荐阅读
相关推荐
深色模式适配指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验