使用css变量实现换肤

实现css换肤的方案有很多,可以使用less和sass,原子化css(Tailwind CSS、Windi CSS、UnoCSS...)

其实也可以使用css变量来实现

什么是css变量

自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: --main-color: black;),由 var() 函数来获取值(比如: color: var(--main-color);

为什么要用它

同样一个颜色值可能在很多地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换(想想都头大)。这个时候css变量的好处就体现出来了,自定义属性在某个地方存储一个值,然后在其他许多地方引用它。另一个好处是语义化的标识。比如,--default-text-color 会比 #00f112 更易理解,尤其是这个颜色值在其他上下文中也被使用到。自定义属性受级联的约束,并从其父级继承其值。

如何使用

css变量是以两个减号(--)开头(因为$被sass用掉了,@被less用掉了 哈哈哈哈),后面的化就基本属于随便写了(CSS选择器不能是数字开头,JS中的变量是不能直接数值的,但是,在CSS变量中,这些限制通通没有,可以是数字,很多博文说可以是汉字,现在应该是不行了,会报错了)

css 复制代码
:root {
  --1:#fff ;
}

body {
  background-color: var(--1);
}

属性值则可以是任何有效的 CSS 值。和其他属性一样,自定义属性也是写在规则集之内的

一般都是写在根 :root 下面,这样就可以在 HTML 文档的任何地方访问到它了

当然 你也可以把变量放在其他你需要的地方

使用的时候 就用 var(csss变量来使用)

css 复制代码
/* 全局声明 */
:root {
  --default-bg-color: #fff;
}


.className{
 background-color:var(--default-bg-color)
}


/* 局部声明 */
body {
  --foo: #ed145b;
  --bar: #F7EFD2;
}

详解 var()

var函数的第一个参数是自定义属性的名称,如果提供了第二个参数,则表示备用值,当自定义属性值无效时生效。

第二个参数可以嵌套,但是不能继续平铺展开下去了,例如:

css 复制代码
.className{
 background-color:var(--default-bg-color,red) /* --default-bg-color无效的时候 就是红色了 */
}

.demo{
 background-color:var(--default-bg-color,var(--main-bg-color,red)) /* --default-bg-color 和 --main-bg-color 都无效的时候 就是红色了 */
}

在js里面操作css变量

在 JavaScript 中获取或者修改 CSS 变量和操作普通 CSS 属性是一样的:

js 复制代码
// 获取一个 Dom 节点上的 CSS 变量
dom.style.getPropertyValue("--my-var");

// 获取任意 Dom 节点上的 CSS 变量
getComputedStyle(dom).getPropertyValue("--my-var");

// 设置 Dom 节点上的 CSS 变量
dom.style.setProperty("--my-var", '#7F583F');

// 删除变量
document.body.style.removeProperty('--primary'); //局部

需要注意的

  • 变量值只能用作属性值,不能用作属性名

    css 复制代码
    .foo {
      --mt: margin-top;
      /* 很显然,下面是无效的 */
      var(--mt): 20px;
      }
  • 如果变量值是一个字符串,可以与其他字符串拼接

    css 复制代码
      --str1: 'hello';
      --str2: var(--bar)' world';
      // 示例
      body:before {
      content: '--screen-category : 'var(--screen-category);
      }
  • 如果变量值是数值,不能与数值单位直接连用 可以和 calc 配置使用

    css 复制代码
      foo {
      --gap: 20;
      /* 无效 */
      padding-top: var(--gap)px;
      /* 通过calc去计算,有效 */
      padding-top: calc(var(--gap) * 1px);
      }
  • 如果变量值带有单位,就不能写成字符串

    css 复制代码
      .foo {
      --gap: '20px';
      gap: var(--foo); /* 不生效 不能写成字符串 */
      }
    
    
      .foo {
      --gap: 20px;
      gap: var(--foo);    /* 有效 */
      }

实操

来实现一个小demo(因为是小demo,重点在实现功能,所以很多方便开发的工程化配置就没搞)

有三个按钮 点击不同的按钮 需要实现不同主题色的切换

js 复制代码
  const [currentColor, setCurrentColor] = useState(
    sessionStorage.getItem("homeColor") || "themeGreen"
  );
  const setBgColor = (str: string) => {
    setCurrentColor(str);
    sessionStorage.setItem("homeColor", str);
  };
  const items = [
    {
      key: "1",
      label: (
        <span
          className={cx("green", currentColor === "themeGreen" && "active")}
          onClick={() => {
            setBgColor("themeGreen");
          }}
        >
          绿色
        </span>
      ),
    },
    {
      key: "2",
      label: (
        <span
          className={cx("yellow", currentColor === "themeYellow" && "active")}
          onClick={() => {
            setBgColor("themeYellow");
          }}
        >
          黄色
        </span>
      ),
    },
    {
      key: "3",
      label: (
        <span
          className={cx("blue", currentColor === "themeBlue" && "active")}
          onClick={() => {
            setBgColor("themeBlue");
          }}
        >
          蓝色
        </span>
      ),
    },
  ];

配置css变量

注意:三个主题类名下面都有一个共同的变量 --text-27282c

点击不同的颜色按钮 看看 变化

原理就是 利用本地储存来获取当前的主题类名,然后在需要做换肤的地方使用css变量,但是css变量是同一个,主题类名下这个css变量却可以是不同的值,利用这个就实现了简单换肤

相关推荐
Myli_ing41 分钟前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
dr李四维1 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
雯0609~1 小时前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ1 小时前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z1 小时前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
彭世瑜2 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4042 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish2 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five2 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序2 小时前
vue3 封装request请求
java·前端·typescript·vue