深入理解 CSS 变量 var() :实现主题换肤与代码功能

笔记哥 / 05-06 / 43点赞 / 0评论 / 415阅读
曾经主题切换功能可以作为软件中亮眼的卖点存在,毕竟那时候要实现换肤可不容易,一套主题一套样式,这代码的重复率嗖嗖嗖的就涨上去了~~当然也可以借助 `CSS 预编译` 语言编译出多套 CSS 样式表。 没有用觉得我们其实并不需要多套样式表实现换肤?我们只是想要一个像 JS 设计模式中的适配器,约定好规则,不同的主题按照约定规则进行适配即可。 ## CSS 变量 什么是变量? 就是在一个地方定义,可到处使用的东西。遇到不满意的时候,也可以随时进行改变。嘿...不满意就换这不是理想中的生活吗?扯远了~~ CSS 变量(又称为自定义属性),可以让开发者集中管理 CSS 中可复用的值,比如:颜色,间距,字体大小等等一切 CSS 中的属性值。 ### 变量声明规则 在 CSS 中,变量名必须以 `--` 开头,比如:`--base-font-size`、`--base-color` 等,需注意,变量名是区分大小写的,如 `--a` 和 `--A` 是两个不同的变量。 虽然变量名的书写规范没强制要求以短横线 `-` 分割,但为了与 css 属性名保持一致,还是建议使用短横线分割,不建议使用驼峰命名,比如 `--baseFontSize` 不推荐,但要这么写代码也能运行。 在声明一个变量也可以使用另一个变量作为变量值。 语法: ```css --base-font-size: 24px; --base-color: #333; --base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); /* 使用另一个变量,并使用默认值 */ --base-border: 2px solid var(--base-color, red); ``` ### 变量申明位置 如果全局使用的变量,可以使用 `:root` 选择器声明: ```css :root { --base-font-size: 24px; --base-color: #333; --base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); } ``` 局部变量可以在选择器中声明,变量名相同情况下,局部变量会覆盖全局变量: ```css .box { --base-font-size: 18px; --box-color: #666; --box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); } ``` ### 变量使用 在 CSS 中,要使用变量必须要用到 `var()` 函数,`var()` 函数的作用就是去获取变量的值,语法如下: ```css .box { font-size: var(--base-font-size); color: var(--base-color); box-shadow: var(--base-shadow); } /* 以上代码等价于 */ .box { font-size: 24px; color: #333; box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); } ``` 示例: ```html
box 中的文字内容
``` 效果: ![](https://cdn.res.knowhub.vip/c/2505/10/b2baf171.png?G1QAAMTsdJzIJ5qg26hD2jvFHc2ARBVBpZ71es9Z%2byb6fhfIFZ%2fR%2bvT94Q%2btTyethppJIApF8DAGEktWDcZWBMVSXMMB) ### var() 默认值 `var()` 的第二个参数可以设置一个默认值,如果获取的变量没有设置,则使用默认值进行属性赋值,可以理解为 `山中无老虎,猴子称大王`。 示例: ```html
box 中的文字内容
``` font-size 和 color 的值都有定义,所以会使用的定义的值,而 background-color 没有定义,所以会使用默认值。效果: ![](https://cdn.res.knowhub.vip/c/2505/10/3a3a73ed.png?G1UAAMTydJz4%2b%2beIbqMO3yaKRJuBijSCSj3r9fz%2fPpfI%2b7nBcrxnH8vPh1%2f0sVzYCloVgxFECCgKJFIrgtKQsiIz7uk%3d) ### 变量覆盖 有时候可能我们不想要默认的变量值,而是需要特殊设定。比如某些三方组件里面使用 root 声明了变量,这时候要想覆盖 root 声明的变量,应该怎么做? **变量覆盖规则:** 1、a.css 和 b.css 同时使用 root 声明了同一个变量,那么跟引入两个 css 文件的顺序有关,后引入的文件会覆盖前一个。 2、`:root` 声明的变量,可以使用 `:root:root` 覆盖。 3、局部变量优先级高于全局变量。 比如有如下两个 CSS 代码文件: a.css 文件: ```css :root { --base-font-size: 24px; --base-color: #333; --base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); } ``` b.css 文件: ```css :root { /* 同时使用 root 声明的变量与引入的顺序有关 */ --base-color: red; } :root:root { /* 此处声明会覆盖 a.css 文件中的 --base-font-size。 不论 a.css 在前,还是在后,都会生效。 */ --base-font-size: 16px; } .box { border: 2px solid rgba(255, 71, 87,0.3); margin: 20px 0; width: 400px; height: 120px; font-size: var(--base-font-size, 12px); color: var(--base-color); box-shadow: var(--base-shadow); background-color: var(--base-bg-color, rgba(255, 71, 87,0.1)); } .box:nth-child(1) { /* 局部变量优先级最高 */ --base-shadow: 0 0 0 6px rgba(0, 0, 0, 0.3); } ``` **a.css 在 b.css 之前引入示例:** ```html
box1 中的文字内容
box2 中的文字内容
``` 效果: ![](https://cdn.res.knowhub.vip/c/2505/10/13d0e813.png?G1MAAMT0bJzoaVrUNvqh%2f4lHQjMgUUVQqWe93nv3aUTf7wyW%2bMw%2blp8Pf%2bhjOallWCEGKxRBIydAIMlqkCqibBr3dA%3d%3d) **b.css 在 a.css 之前引入示例:** ```html
box1 中的文字内容
box2 中的文字内容
``` 效果: ![](https://cdn.res.knowhub.vip/c/2505/10/82033c8d.png?G1UAAMTsdJzIJ02QbqMO2jvFHc1ARRpBpZ71es9Z%2byb6%2fiYQjc%2bofbb94Re1z0bmCZ5JIAZDCEgMKGthDczq5leWEtdo) **由于变量的覆盖特性,所以不建议到处声明变量,应该集中管理,在固定文件中声明 CSS 变量!!** ## 主题换肤 一个简单的换肤示例: ```html
box 中的文字内容
``` 效果: ![](https://cdn.res.knowhub.vip/c/2505/10/639f7c81.gif?G1QAAMTc2vOlux1Ts9%2fToCVYBtoMSFQRVOpZr2fvf50i%2fXWCFq%2bvjenrwx%2famC6pZtQiBBMSgkdWwEjFEdRg0ApG7zc%3d) ## 写在最后 CSS 变量可以让我们很方便的进行主题换肤,也让前端可以集中管理重复的颜色、字体、边框等属性,增强了代码的可维护性。