1. 前言
本文介绍 CSS 的自定义属性(变量)来实现样式、动画等 CSS 的复用。都是知道在 CSS 和 JS 复用一个很重要的事情,比如 JS 的函数封装,各个设计模式的使用等等,CSS 中样式的复用,同样重要。MDN 使用 CSS 自定义属性(变量):自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: --main-color: black;),由 var() 函数来获取值(比如: color: var(--main-color);)复杂的网站都会有大量的 CSS 代码,通常也会有许多重复的值。
2. 实例:限定文本行数
2.1 效果图

2.2 原样式
css
.rui-limit1 {
overflow: hidden;
text-overflow: ellipsis;
display: box;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
/*! autoprefixer: off */
}
.rui-limit2 {
overflow: hidden;
text-overflow: ellipsis;
display: box;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
/*! autoprefixer: off */
}
.rui-limit3 {
overflow: hidden;
text-overflow: ellipsis;
display: box;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
/*! autoprefixer: off */
}
可以看到每一个都将样式写了一遍,限制多少行,改变对应的数量,当然也可以将三个整合一起,然后修改每一个的 -webkit-line-clamp 值,就能简化,然后自定义行数的时候直接修改 -webkit-line-clamp 的值就可以。但是 -webkit-line-clamp 属性相对还是长了一点,对于不经常使用的人来说,不一定能记住,因此在此基础上引入 CSS 变量,来解决这个问题。
2.3 引入变量的样式
css
.rui-limit{
--limit-val: 1;
overflow: hidden;
text-overflow: ellipsis;
display: box;
display: -webkit-box;
-webkit-line-clamp: var(--limit-val);
-webkit-box-orient: vertical;
/*! autoprefixer: off */
}
.limit2{
--limit-val: 2;
}
.limit3{
--limit-val: 3;
}
2.4 改变变量来修改限制行数
ini
style="--limit-val:5"

当然变量名字随便定义一个团队认可且好记的变量就可以!
3. 实例:按钮
3.1 效果图

3.2 CSS 实现
css
.rui-btn {
--btn-h: 80px;
--btn-w: 100%;
--btn-c: #555555;
--btn-bg: #fff;
--btn-rad: 0px;
--btn-bc: #555555;
--btn-bw: 1px;
--btn-fs: 30px;
--btn-b: var(--btn-bw) solid var(--btn-bc);
flex: none;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
height: var(--btn-h);
width: var(--btn-w);
border-radius: var(--btn-rad);
color: var(--btn-c);
font-size: var(--btn-fs);
border: var(--btn-b);
background: var(--btn-bg);
user-select: none;
}
.rui-btn-none {
--btn-b: none;
}
.rui-bg1 {
--btn-bg: #f6ed8d;
}
.rui-bg2 {
--btn-bg: #7de3c8;
}
.rui-bg3 {
--btn-bg: linear-gradient(to left, #04e6fb, #9006fb);
}
.rui-circle-btn {
--btn-rad: 40px;
}
3.3 DOM 结构
javascript
import { View } from "@tarojs/components";
import "./index.scss";
const Btn = (props) => {
return (
<View className="rui-limit-page-content">
<View className="rui-fwb rui-fs36">默认</View>
<View className="rui-flex-fw">
<View className="rui-btn">按钮</View>
</View>
<View className="rui-fwb rui-fs36">无边框</View>
<View className="rui-flex-fw">
<View className="rui-btn rui-btn-none rui-bg1">按钮</View>
</View>
<View className="rui-fwb rui-fs36">圆角</View>
<View className="rui-flex-fw">
<View className="rui-btn rui-btn-none rui-circle-btn rui-bg2">
按钮
</View>
</View>
<View className="rui-fwb rui-fs36">渐变</View>
<View className="rui-flex-fw">
<View className="rui-btn rui-btn-none rui-bg3">按钮</View>
</View>
</View>
);
};
export default Btn;
3.4 总结
通过将按钮的常用样式属性的值通过自定义变量读取,然后其他按钮就通过修改对应变量来改变样式。其实本质上和修改对应的属性是一样,只是通过变量,直接修改的是属性值,就不用写那么长的属性名。有一定简化,但是相对没有那么明显。
4. 实例:动画
4.1 效果图

4.2 效果分析
- 从效果图种可以看出,存在上下移动动画,顺时针旋转,逆时针旋转三种动画;
- 各个动画的时间还不相同;
- 按照开始的写法,需要定义最少三个动画,但是使用 CSS 变量,就能将动画减少到两个;
- 通过 CSS 变量修改每个动画的执行时间;
- 通过 CSS 变量确定每个 class 执行的动画名称。
4.3 CSS 实现
css
@keyframes jump {
0%,
100% {
transform: translateY(10px);
}
50% {
transform: translateY(-10px);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(var(--load-deg));
}
}
:root {
--load-w: 80px;
--load-h: 80px;
--load-rad: 50%;
--load-name: spin;
--load-deg: 360deg;
}
.rui-nb-spinner,
.rui-top-spinner,
.rui-tb-spinner,
.rui-tl-spinner::before,
.rui-tl-spinner::after,
.rui-reverse-spinner::before,
.rui-reverse-spinner::after,
.rui-loading-dot,
.rui-loading-dot::before,
.rui-loading-dot::after {
--load-time: 1s;
--load-dt: 0s;
width: var(--load-w);
height: var(--load-h);
border-radius: var(--load-rad);
animation: var(--load-name) var(--load-time) var(--load-dt) linear infinite;
}
.rui-loading-dot {
--load-w: 20px;
--load-h: 20px;
--load-ml: 30px;
--load-dt: -0.8s;
--load-bc: #5e85d1;
--load-name: jump;
background: var(--load-bc);
margin-left: var(--load-ml);
position: relative;
&::before,
&::after {
--load-left: 0;
content: "";
position: absolute;
top: 0;
left: var(--load-left);
background: var(--load-bc);
}
&::before {
--load-left: -30px;
--load-dt: -0.4s;
}
&::after {
--load-left: 30px;
--load-dt: 0s;
}
}
.rui-nb-spinner {
background: transparent;
border-top: 4px solid #5e85d1;
border-right: 4px solid transparent;
}
.rui-top-spinner {
border: 4px solid #222;
border-top-color: #5e85d1;
}
.rui-tb-spinner {
border: 4px solid #222;
border-top-color: #5e85d1;
border-bottom-color: #5e85d1;
}
.rui-tl-spinner {
width: var(--load-w);
height: var(--load-h);
&::after {
content: "";
position: absolute;
border: 4px solid transparent;
border-top-color: #5e85d1;
border-left-color: #5e85d1;
}
&::before {
--load-time: 2s;
content: "";
position: absolute;
border: 4px solid transparent;
border-top-color: #222;
border-left-color: #222;
}
}
.rui-reverse-spinner {
--load-w: 100px;
--load-h: 100px;
width: var(--load-w);
height: var(--load-h);
display: flex;
align-items: center;
justify-content: center;
&::before {
--load-time: 1.5s;
content: "";
position: absolute;
border: 4px solid transparent;
border-top-color: #5e85d1;
border-left-color: #5e85d1;
}
&::after {
--load-small-w: 15px;
--load-deg: -720deg;
--w: calc(100px - var(--load-small-w) * 2);
content: "";
width: var(--w);
height: var(--w);
border-radius: var(--load-rad);
box-sizing: border-box;
position: absolute;
border: 4px solid transparent;
border-top-color: #03a9f4;
border-left-color: #03a9f4;
}
}
4.4 DOM 结构
javascript
import { View } from "@tarojs/components";
import "./index.scss";
const Loading = (props) => {
return (
<View className="rui-limit-page-content">
<View className="rui-grid-content">
<View className="rui-grid-item">
<View className="rui-loading-dot"></View>
</View>
<View className="rui-grid-item">
<View className="rui-nb-spinner"></View>
</View>
<View className="rui-grid-item">
<View className="rui-top-spinner"></View>
</View>
<View className="rui-grid-item">
<View className="rui-tb-spinner"></View>
</View>
<View className="rui-grid-item">
<View className="rui-tl-spinner2"></View>
<View className="rui-tl-spinner"></View>
</View>
<View className="rui-grid-item">
<View className="rui-reverse-spinner"></View>
</View>
</View>
</View>
);
};
export default Loading;
5. 总结
- 通过上边三个实例,可以看出 CSS 变量起到的作用,大大的简化了 CSS 样式,代码的复用率变大;
- 同时不再需要每次都修改 CSS 的属性,直接通过修改值,来改变 CSS 的渲染结果;
- 【CSS】 ---- CSS 实现图片随鼠标移动局部放大特效的实现也是通过修改属性的值,也就是通过 CSS 变量来改变属性值实现。