【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 变量来改变属性值实现。
相关推荐
Bdygsl11 分钟前
前端开发:CSS(2)—— 选择器
前端·css
斯~内克18 分钟前
CSS包含块与百分比取值机制完全指南
前端·css·tensorflow
百万蹄蹄向前冲6 小时前
秋天的第一口代码,Trae SOLO开发体验
前端·程序员·trae
努力奋斗17 小时前
VUE-第二季-02
前端·javascript·vue.js
路由侠内网穿透7 小时前
本地部署 SQLite 数据库管理工具 SQLite Browser ( Web ) 并实现外部访问
运维·服务器·开发语言·前端·数据库·sqlite
一只韩非子7 小时前
程序员太难了!Claude 用不了?两招解决!
前端·claude·cursor
JefferyXZF7 小时前
Next.js项目结构解析:理解 App Router 架构(二)
前端·全栈·next.js
Sane7 小时前
react函数组件怎么模拟类组件生命周期?一个 useEffect 搞定
前端·javascript·react.js
gnip7 小时前
可重试接口请求
前端·javascript
若梦plus8 小时前
模块化与package.json
前端