当前位置:网站首页>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
附录
边栏推荐
猜你喜欢
【HQL】(二) 查询使用正则表达式做列选择
Hook初探索
【Arduino】关于“&”和“|” 运算-----多个参数运算结果异常的问题解决
微信小程序 自定义tabBar
Kettle Spoon 安装配置详解
Sentinel初次使用Demo测试
自监督论文阅读笔记 Self-Supervised Visual Representation Learning with Semantic Grouping
Ansible installation and deployment detailed process, basic operation of configuration inventory
自监督论文阅读笔记 SimCLRV2 Big Self-Supervised Models are Strong Semi-Supervised Learners
优雅的拦截TabLayout的点击事件
随机推荐
Apache2-XXE漏洞渗透
【 command execution and middleware loopholes 】
Oracle 密码策略详解
block底层探索
Mysql 存储过程详解(procedure)
【Yarn】yarn常用命令 查看日志和Kill任务
动漫 吞噬星空
自监督论文阅读笔记DisCo: Remedy Self-supervised Learning on Lightweight Models with Distilled Contrastive
Apache2-XXE vulnerability penetration
深度学习基本概念
中国柔性制造系统(FMS)市场发展动态及未来趋势预测报告2022~2028年
IPC 通信 - IPC
当奈飞的NFT忘记了web2的业务安全
Oracle 注释详解(--、/**/、rem)
滚动条 scrollbar 和scrollbar-thumb 样式
自监督论文阅读笔记 TASK-RELATED SELF-SUPERVISED LEARNING FOR REMOTE SENSING IMAGE CHANGE DETECTION
Execute the mysql script file in the docker mysql container and solve the garbled characters
二叉树常见的问题和解决思路
docker mysql 容器中执行mysql脚本文件并解决乱码
自监督论文阅读笔记Efficient Self-supervised Vision Pretraining with Local Masked Reconstruction