日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > CSS >内容正文

CSS

CSS | 使用 PostCSS 插件让 Web 应用支持暗黑模式

發(fā)布時間:2023/12/31 CSS 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CSS | 使用 PostCSS 插件让 Web 应用支持暗黑模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1 概述

通過使用 CSS 變量,可以實現(xiàn)暗黑模式。比如使用媒體查詢器:

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

如果有很多顏色需要處理,此時就要用到 CSS 變量。

: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); }

可以看到這種辦法代碼簡單易懂,問題是var關鍵字不兼容 IE 瀏覽器。

還有一個辦法,就是使用 less.js 實時編譯 CSS 代碼,比如:

<script src="less.js"></script> <script> less.modifyVars({ '@text-color': '#fff', '@bg-color': '#000' }); </script>... var less = require("less"); var fs = require("fs");fs.readFile("./index.less", "utf-8", (err, str) => {less.render(str,{paths: [".", "./components"], // 搜尋由 @import 指向的目錄compress: true, modifyVars: {"@text-color": "#fff","@bg-color": "#000",},},function (e, output) {console.log(output.css);}); });

使用 less 的缺點是,當點擊切換按鈕時,會導致卡頓。

當然,也可以通過DOM動態(tài)更新 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); }

使用 DOM 動態(tài)更改的辦法,需要把顏色單獨作成樣式文件,導致配置繁瑣。

2 什么是 PostCSS ?

PostCSS 核心包含一個生成 CSS 抽象語法樹的AST 解析器,能將 CSS 代碼抽象成一個節(jié)點樹。如果代碼發(fā)生更改,節(jié)點樹也會更新。

核心過程是 解析 => 轉(zhuǎn)換 => 生成,類似 Babel。形式如下圖所示:

3 舉個例子

比如下面的 .less 代碼:

我們要將其轉(zhuǎn)換為:

Wepack 的配置如下:

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

3.1 編寫 PostCSS 插件

我們可以使用 postcss-plugin-boilerplate腳手架,這個腳手架可以創(chuàng)建一個 postcss-plugin,并且還可以配置jest單元測試。流程圖如下:

當然,也可以在項目根目錄下手動創(chuàng)建一個 PostCSS 插件。

// test-plugin.js var postcss = require("postcss");module.exports = postcss.plugin("pluginname", function (opts) {opts = opts || {}; // plugin 參數(shù)return function (root, result) {// Transform the CSS AST}; });

然后,將其放入 postcss.config.js 配置文件中。

module.exports = {plugins: [require('./test-plugin'),require('autoprefixer')] };

編寫代碼,完成插件功能。

var postcss = require("postcss");module.exports = postcss.plugin("postcss-backwards", function (opts) {opts = opts || {};return function (root, result) {// Iterate over all style nodesroot.walkDecls((declaration) => {declaration.value = declaration.value.split("").reverse().join("");});}; });

這是一個沒有實際意義的插件,僅作教學使用。

3.2 如何使用 PostCSS 實現(xiàn)暗黑模式支持 ?

將less文件導入項目。

import "./default-theme.less"; import "./dark-theme.less";

component.less

.box{width: 100px;height: 100px;border: 1px solid @border;background-color: @bg;color: @color; }

default-theme.less

@import "./component";@border: #333; @color: #000; @bg: #fff;

dark-theme.less

@import "./component";@border: #999; @color: #fff; @bg: #000;

轉(zhuǎn)換模塊

function isEmpty(arr) {return Array.isArray(arr) && arr.length === 0; }const hasColorProp = (colorProps, declProp) =>colorProps.some((prop) => declProp.includes(prop));module.exports = (opts = {}) => {if (!opts.colorProps) {opts.colorProps = ["color", "background", "border", "box-shadow", "stroke"];}return (root) => {let theme;const file = root.source.input.file || "";const matched = file.match(/(?<theme>[a-zA-Z0-9]+)-theme.(less|css|scss|sass)/);if (matched && matched.groups.theme !== "default") {theme = matched.groups.theme;} else {if (process.env.NODE_ENV == "test") {theme = "test";}}if (theme) {root.walkRules((rule) => {rule.walkDecls((decl) => {if (!hasColorProp(opts.colorProps, decl.prop)) {decl.remove();}});if (isEmpty(rule.nodes)) {rule.remove();} else {rule.selector = rule.selector.replace(/\n/g, "").split(",").map((s) => `.${theme} ${s}`).join(",\n");}});}}; };

4 實施步驟

4.1 通過文件名來確定是否需要生成皮膚樣式

const file = root.source.input.file || "";const matched = file.match(/(?<theme>[a-zA-Z0-9]+)-theme.(less|css|scss|sass)/ );

4.2 刪除不包含顏色的樣式

只保留邊框顏色、背景顏色和包含顏色的 CSS 屬性。并且,刪除不包含 CSS 屬性的選擇器。

["color", "background","border","box-shadow","stroke",]

4.3 配置規(guī)則

module.exports = [{prop: ["background-color", "background"],from: ["#fff", "#ffffff", "@white"],to: "@component-background",},{prop: ["border", "border-color"],from: ["#D3D9E4", "#D3D9E2"],to: "@border-color",},{prop: ["color"],from: ["#666E79", "#5C6268"],to: "@text-color",} ];

4.4 執(zhí)行轉(zhuǎn)化

const syntax = require("postcss-less"); var fs = require("fs"); const path = require("path"); const rules = require("./rule.js");var glob = require("glob");function log(file, node, to) {console.log("\x1b[32m",`convert ${file} ${node.source.start.line}:${node.source.start.column} ${node.parent.selector} ${node.prop} from ${node.value} to ${to}`); }let codes = {};// options is optional glob("./src/**/*.less", function (er, files) { files.forEach((file) => {var ast = syntax.parse(file);// traverse AST and modify itast.walkDecls(function (node) {rules.forEach((item) => {if (item.prop.includes(node.prop) && item.from.includes(node.value)) {node.value = item.to;log(file, node, item.to);}});});fs.writeFileSync(path.resolve(file), syntax.nodeToString(ast));}); });

總結

以上是生活随笔為你收集整理的CSS | 使用 PostCSS 插件让 Web 应用支持暗黑模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。