当前位置:网站首页>Dynamic adjustment subject web system?Look at this one is enough
Dynamic adjustment subject web system?Look at this one is enough
2022-08-03 05:55:00 【ice breaker】
动态调整web系统主题? 看这一篇就够了
A scheme for building a flexible system page theme
前置技术点
Before reading this article,It is best to have the following knowledge
css
基础知识dart-sass
preprocessor programmingwebpack
以及postcss
tailwindcss
含有jit
的v2/v3
前言
我们在日常生活中,Whether it's visit the web site,手机App,还是小程序,时常会用到 切换主题 这个功能.It can provide users with a certain ability to customize the display interface,Also can change the theme of the mobile phone system level,比如 light(明亮模式)
和 dark(黑暗模式)
.
So how do you let's write the application,在改动不大的情况下,Can you quickly adapt to multiple themes??
This requires a plan.
方案设计
方案参考
Here we use the most familiar ones for programmers Github
为例,It's theme switching does this:
它在 根元素 That's a few presets css
变量值, 然后通过 js
去动态修改 html
on the root element data-color-mode
和 data-dark-theme
the values of these properties,从而让不同的 css
selector selects this root element,And use this to dynamically switch :root
中的 css
变量的值.
At the same time, these variables are widely used in various 原子化的 class
和 @apply
中,Once the variable is changed,all use theseclass
The controls and layout are affected,Naturally the whole theme is changed.
1. 提炼css变量
The first thing we need to do is to extractcss变量,These are mainly provided by designers.
这里以颜色为例,主要包含 polymorphism of the same color
,The color of each state of the control
,提示警告错误
,字体中,标题,副标题,正文,提示的颜色
等等.Of course like the font size,The same goes for shadows.
这方面就不细说了,After extraction to the variable named after we can begin to work:
// constants.scss
// 这是一个 scss 的 map数据结构,Save the default initial value
$root-vars:(
--color-fg-default: #adbac7,
--color-fg-muted: #768390,
--color-fg-subtle: #545d68,
--color-fg-on-emphasis: #cdd9e5,
--color-scale-gray-0: #cdd9e5,
--color-scale-gray-1: #adbac7,
--color-scale-gray-2: #909dab,
--color-scale-gray-3: #768390,
// ...
)
可以注意到,In the maintenance of the variable,Color is the majority,And we save all the colorshex
格式,并没有按照rgba
的格式,put transparency(opacity
)保存下来, 这是为什么? The answer will be revealed later.
接着,maintain thissass:map
,We write a tool class util.scss
to convert the color variable to a string:
// util.scss
@use 'sass:color';
@use 'sass:meta';
@function getRgbString($color) {
@if (meta.type-of($color) == color) {
@return color.red($color) color.green($color) color.blue($color);
} @else {
@return $color;
}
}
then in the global style global.scss
中添加:
// global.scss
@use './constants.scss' as C;
@use './util.scss' as Util;
:root {
@each $var, $color in C.$root-vars {
#{$var}: Util.getRgbaString($color);
}
}
In this way, our variable default value strings are added :root
根元素中:
/* result */
:root{
--color-canvas-default-transparent: 34 39 46;
--color-marketing-icon-primary: 108 182 255;
--color-marketing-icon-secondary: 49 109 202;
--color-diff-blob-addition-num-text: 173 186 199;
--color-diff-blob-addition-fg: 173 186 199;
--color-diff-blob-addition-num-bg: 87 171 90;
--color-diff-blob-addition-line-bg: 70 149 74;
--color-diff-blob-addition-word-bg: 70 149 74;
--color-diff-blob-deletion-num-text: 173 186 199;
...
}
Note here that strings are stored in global variables,not the color variable itself.
但是有了这些,没有对应的 class
和 scss
变量,We are still very bad at using these variables,So how to carry out engineering to improve our development efficiency??接下来重点来了.
2. scss 与 js通信,动态生成 scss Variables and atomization class
首先编写 export.scss
for exposing objects to js
使用:
// export.scss
@use './constants.scss' as C;
@use './util.scss' as Util;
:export {
@each $var, $color in C.$root-vars {
#{$var}: Util.getRgbaString($color);
}
}
然后利用 webpack sass-loader
中 js
和 scss
的通信方法,就可以生成:
variables.scss
(全局scss
变量文件)extendColors.cjs
(tailwindcss colors
配置文件)
// generator.js 生成器
import variables from '@/assets/scss/export.scss'
// Simple and easy to remove the prefix
removeColorPrefix(str) {
return str.substring(8)
}
// 此时的 variables 是一个 object
// 那么scssThe template for the global variable is generated as:
scssFilterShadow(str) {
return `rgb(var(${
str}))`
}
// scss模板为
${
{
removeColorPrefix(k) }}:{
{
scssFilterShadow(k) }};
// 此时 原子化的 `tailwindcss colors` 文件生成为:
jsFilterShadow(str) {
return `withOpacityValue('${
str}')`
}
// tailwindcss模板为
'{
{ removeColorPrefix(k) }}':{
{
jsFilterShadow(k) }},
通过这种方式,We write the generated results to variables.scss
和 extendColors.cjs
文件内,So it is convenient to maintain so many in the first step. css变量
,All quickly and easily converted to equivalent scss变量
和 tailwindcss 配置
3. 全局scssfile variable injection
生成 variables.scss
后,我们可以配置一下 sass-loader
to make the variables in it not need to显式引入,In the global to take effect:
// sass-loader
{
additionalData: '@use "@/assets/scss/variables.scss" *;',
}
In this way, we can use any vue <style lang="scss">
, 或者 .scss
Use to all files variables.scss
中声明的变量了.
4. 原子化的 class 生成
生成 extendColors.cjs
后,我们在里面添加:
function withOpacityValue(variable) {
return ({
opacityValue }) => {
if (opacityValue === undefined) {
return `rgb(var(${
variable}))`
}
return `rgb(var(${
variable}) / ${
opacityValue})`
}
}
This is to combine jit
引擎,to dynamically adjust the transparency of all colors.有了它,We can write the following code:
h1{
@apply text-header-text;
// 等价于
// color: rgb(var(--color-header-text))
}
h2{
@apply text-header-text/70;
// 等价于
// color: rgb(var(--color-header-text) / 0.7)
}
This is also we will give the root element css变量
赋值为 R G B
格式的原因了!
本质上讲,is that we are using native css
中 rgb
(rgba
是rgb
的别名) Constructor to create a color variables:
/* rgb的函数Syntax */
rgb(255,255,255) /* white */
rgb(255,255,255,.5) /* white with 50% opacity */
rgb(255 255 255) /* CSS Colors 4 space-separated values */
rgb(255 255 255 / .5); /* white with 50% opacity, using CSS Colors 4 space-separated values */
From the code snippet above,我们可以看到,列出的 rgb(R G B / A)
Is using the plan now.
Of course, we also can change the above getRgbString
和 withOpacityValue
这2个方法,把 ,
Add this separator,再把 /
去除,从而使用它 rgb(R,G,B,A)
this construction.
In this way, we can generate such a style when we use it:
.neutral{
background-color: rgb(var(--color-neutral-muted));
&:hover{
background-color: rgb(var(--color-neutral-muted) / 0.4);
}
}
Is it very flexible?
接下来只要把 extendColors.cjs
导入进 tailwind.config.js
配置中,就可以自动生成 class
和 vscode
's smart tips:
// tailwind.config.js
const extendColors = require('./client/theme/extendColors.cjs')
const colors = require('tailwindcss/colors')
module.exports = {
// ...
theme:{
extend:{
colors:{
...extendColors.colors,
}
//...
},
colors:{
transparent: 'transparent',
current: 'currentColor',
black: colors.black,
white: colors.white,
gray: colors.gray,
},
// ...
}
// ...
}
这样,We just need to change the variables that the theme changes depend on,Write into various controls,layout,容器中去,所有的 css
变量就生效了,Switch the theme is very convenient.
5. Dynamically modify root node variables
Our application themes in many scenarios,Instead of choosing from several preset solutions for front-end maintenance,Instead, it is configured by the user,保存在数据库中,Client can get after each request.
This way of obtaining means that the front end is here,Only keep a set of default presets.So we usually get the topic data given by the backend after,动态的修改 css变量
的值.
具体怎么做呢?本质上就是调用 CSSStyleDeclaration.setProperty()
,来设置 document.documentElement
的变量值.
to make it better,我们可以进行封装,And establish a set of browser local caching mechanism,These are no longer described here,条条大道通罗马.
兼容性
Note that this plan is to give up IE
的! (都上 tailwindcss
了),The rest of the browser compatibility is good.
总结
这种方式,In fact, a lot of css
, sass
, webpack
,tailwindcss
的特性,The author looks back,It was found that after the implementation of this scheme,Good is very good.
变量,原子化class, Public extraction and smart prompts all in one place,It is to have a full understanding of the above technical points.
If you have suggestions or better solutions for this article,Also welcome to contact the author to discuss.
The author's contact information
附录
边栏推荐
猜你喜欢
嵌入式实验二注意点
MySQL 下载和安装详解
深度学习基本概念
【DC-5靶场渗透】
嵌入式实验三(代码几乎都要改才能运行)
自监督论文阅读笔记Efficient Self-supervised Vision Pretraining with Local Masked Reconstruction
Delightful Nuxt3 Tutorial (1): Application Creation and Configuration
当我们在看Etherscan的时候,到底在看什么?
自监督论文阅读笔记 DetCo: Unsupervised Contrastive Learning for Object Detection
block底层探索
随机推荐
取某一区间中素数的个数--洛谷P1865 A % B Problem
交叉熵(第六周)
spark sql 报错 Can‘t zip RDDs with unequal numbers of partitions
3588. 排列与二进制
动漫:海贼王女
用户登录验证程序的实现
arm64麒麟安装paddlehub(国产化)注意事项
Qlik Sense 判空详解(IsNull)
Ansible installation and deployment detailed process, basic operation of configuration inventory
【XSS,文件上传,文件包含】
中国融资租赁行业市场投资分析与前景战略规划建议报告2022~2028年
寄存器常见指令
Hook初探索
【IDEA】字体修改-护眼主题-文件注释头设置
ASP.NET MVC:自定义 Route
MySQL 安装报错的解决方法
深度学习理论课程第八、九、十章总结
理论上的嵌入式跑马灯
二叉树常见的问题和解决思路
block底层探索