首页 > 其他分享 >使用 PostCSS 插件让你的网站支持暗黑模式

使用 PostCSS 插件让你的网站支持暗黑模式

时间:2022-10-07 18:33:41浏览次数:49  
标签:插件 less color postcss border theme 暗黑 PostCSS css

使用 PostCSS 插件让你的网站支持暗黑模式_解析器

最近公司需要给多个 webapp(大概20+)加上多皮肤的功能,原先默认是白色皮肤,我们先从暗黑模式入手,从而逐渐实现多皮肤功能。本篇记录下实现思路。

换肤方案

css variables

css variables 是 Web 标准实现了对深色模式的支持, 以下代码通过 CSS 媒体查询,最简单的实现。

:root {
color-scheme: light dark;
background: white;
color: black;
}

@media (prefers-color-scheme: dark) {
:root {
background: black;
color: white;
}
}

颜色较多的情况下,使用 css variables

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color)
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便;

缺点:存在浏览器兼容性,需要 edge16+ 才支持,老项目实现起来, 需要重构 css, 所以对我司来说就不适用了,如果是新的 webapp,我会毫不犹豫的选择这种方式。

less在线编译

这种方案最典型的例子是 antdtheme.com/​ ,通过​​less modifyVars​​方法 启用对较少变量的运行时修改。使用新值调用时,将重新编译较少的文件,而无需重新加载。

<script src="less.js"></script>
<script>modifyVars({ '@text-color': '#fff', '@bg-color': '#000'</script>

那如果要修改的颜色变量过多,或者样式文件过多,就会造成切换的时候卡顿。

打包多份 css

当然也可以手动打包 2 份 css 样式

var less = require("less");
var fs = require("fs");

fs.readFile("./index.less", "utf-8", (err, str) => {
less.render(
str,
{
paths: [".", "./componnents"], // 为 @import指令指定搜索路径
compress: true, // 压缩
modifyVars: {
"@text-color": "#fff",
"@bg-color": "#000",
},
},
function (e, output) {
console.log(output.css);
}
);
});

然后就可以通过动态插入 css 的方式进行换肤了

function changeTheme(theme) {
const styleCss = document.querySelector("#styleCss");
if (styleCss) {
styleCss.href = `/assets/css/${theme}.css`;
} else {
const head = document.getElementsByTagName("head")[0];
const link = document.createElement("link");
link.id = "styleCss";
link.type = "text/css";
link.rel = "stylesheet";
link.dataset.type = "theme";
link.href = `/assets/css/${theme}.css`;
head.appendChild(link);
}
localStorage.setItem("theme", theme);
}

这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 postcss.

PostCSS

PostCSS 核心包含一个解析器,该解析器生成一个 CSS AST (抽象语法树) ,这是一个解析 CSS 字符串的节点树的表示。当我们在 CSS 抽象语法树中修改一些内容后,PostCSS 将语法树(AST)生成回 CSS 字符串。

核心就是 编译->转换-->生成 是不是跟 babel相似呢?

大家都知道 astexplorer.net/ 这个网站,可以用来写 babel 插件,不知道是否使用过其他解析器?这边选择 CSS 和 postcss 这样就可以将 css 解析成 CSS AST (抽象语法树)了。

使用 PostCSS 插件让你的网站支持暗黑模式_解析器_02

目的

使用 PostCSS 插件让你的网站支持暗黑模式_解析器_03

当前我有一份 less 样式和 2 份颜色变量,我需要生成如下样式:

使用 PostCSS 插件让你的网站支持暗黑模式_JavaScript_04

这样我就可以在 html 跟节点 添加和删除 ​​dark​​ 这个样式来实现换肤了。

或许有同学会问,这里怎么突然变成 less 了?PostCSS 能解析 Less 吗? 答案是不能。 当前假设我们的 webapp 是基于 webpack 构建的。

module: {
rules:[
//...
{
test: /\.less$/i,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'],
},
//...

上面的 loader 的执行顺序是 自右向左

标签:插件,less,color,postcss,border,theme,暗黑,PostCSS,css
From: https://blog.51cto.com/u_15757429/5734852

相关文章

  • 一起来写 VS Code 插件:实现一个翻译插件
    前言上一篇介绍了用​​codesnippets​​​的方式开发一个插件,本文将通过实现一个翻译插件实例的方式来熟悉VSCode插件开发的常见功能和方法。当然大家可以前往VSCo......
  • [参考]2022 IDA插件大赛结果
    2022IDA插件大赛结果Hexray原文地址:2022Plug-InContest(hex-rays.com),本文主要对插件进行转载。Wereceived9interestingsubmissionsthisyear!Asusual,many......
  • 传奇龙族引擎三端插件使用说明
    ​1.解压龙族三端工具包,打开里面的插件文件夹将插件放到游戏版本Mir200里面把插件**“MultiEndEngine.dll”和“MultiEndEngine.Jdk”**复制到你的游戏版本MirServer......
  • C4D 2023插件:Arnold for mac(C4D S2023阿诺德渲染器)
     Arnold是一款先进的蒙特卡洛光线追踪渲染器,专为动画长度和视觉效果的需求而打造。C4DtoA4.4.0使用Arnold7.1.3.1 ,是一个功能版本,带来了对Cinema4D2023中OCI......
  • [转] webpack 插件的作用
      我们需要先安装插件:npmiwebpack-dev-server-D然后修改 package.json文件:"scripts":{"dev":"webpackserve"}, ......
  • Visual Studio Code +PHP开发 推荐插件
    1、PHPIntelephense:超好用php智能代码提示器,支付代码提示、查找定义、类搜索等功能,非常强大2、PHP接口注释插件:安装好后可以使用“/**”快捷键+Tab自动生成接......
  • 源码角度了解Skywalking之tomcat插件的实现
    源码角度了解Skywalking之tomcat插件的实现通过前几篇的文章,我们都知道定义Skywalking的插件都会在resources文件夹下定义一个def文件,标注这个插件的特殊类,来区分插件的不......
  • 移动端网页特效及常用插件
    一、触屏事件(一)触屏事件概述1、移动端浏览器兼容性较好,我们不需要考虑以前JS的兼容性问题,可以放心的使用原生JS书写效果,但是移动端也有自己独特的地方。比如触屏事件tou......
  • 常用的广告拦截插件
    一、AdGuard广告拦截器​ AdGuard广告拦截器是一款可以对抗各式广告的拦截插件,该插件可以拦截包括视频广告、浮动广告以及插播广告在内的绝大部分常见的网站广告。该......
  • 解除一款插件在离线状态下会强制更新
    前言具体哪款插件这里就不说了,本身是免费的,但是会时不时提醒你去更新,提醒就算了,还会计算系统的时间,超过几个月就禁止使用,逼你更新.因为本身老版本的功能一般能满足......