【CSS】---- CSS 变量,实现样式和动画函数复用

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 效果分析

  1. 从效果图种可以看出,存在上下移动动画,顺时针旋转,逆时针旋转三种动画;
  2. 各个动画的时间还不相同;
  3. 按照开始的写法,需要定义最少三个动画,但是使用 CSS 变量,就能将动画减少到两个;
  4. 通过 CSS 变量修改每个动画的执行时间;
  5. 通过 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. 总结

  1. 通过上边三个实例,可以看出 CSS 变量起到的作用,大大的简化了 CSS 样式,代码的复用率变大;
  2. 同时不再需要每次都修改 CSS 的属性,直接通过修改值,来改变 CSS 的渲染结果;
  3. 【CSS】 ---- CSS 实现图片随鼠标移动局部放大特效的实现也是通过修改属性的值,也就是通过 CSS 变量来改变属性值实现。
相关推荐
mCell3 小时前
GSAP ScrollTrigger 详解
前端·javascript·动效
gnip3 小时前
Node.js 子进程:child_process
前端·javascript
excel6 小时前
为什么在 Three.js 中平面能产生“起伏效果”?
前端
excel8 小时前
Node.js 断言与测试框架示例对比
前端
天蓝色的鱼鱼9 小时前
前端开发者的组件设计之痛:为什么我的组件总是难以维护?
前端·react.js
codingandsleeping9 小时前
使用orval自动拉取swagger文档并生成ts接口
前端·javascript
石金龙10 小时前
[译] Composition in CSS
前端·css
白水清风10 小时前
微前端学习记录(qiankun、wujie、micro-app)
前端·javascript·前端工程化
Ticnix10 小时前
函数封装实现Echarts多表渲染/叠加渲染
前端·echarts
用户221520442780010 小时前
new、原型和原型链浅析
前端·javascript