HELLO,这里是大熊的前端开发笔记。
曾经主题切换功能可以作为软件中亮眼的卖点存在,毕竟那时候要实现换肤可不容易,一套主题一套样式,这代码的重复率嗖嗖嗖的就涨上去了~~当然也可以借助 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
<div class="box">
box 中的文字内容
</div>
<style>
:root {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: 400px;
height: 120px;
font-size: var(--base-font-size);
color: var(--base-color);
box-shadow: var(--base-shadow);
}
</style>
效果:

var() 默认值
var()
的第二个参数可以设置一个默认值,如果获取的变量没有设置,则使用默认值进行属性赋值,可以理解为 山中无老虎,猴子称大王
。
示例:
html
<div class="box">
box 中的文字内容
</div>
<style>
:root {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: 400px;
height: 120px;
font-size: var(--base-font-size, 12px); /* 如果没有设置 --base-font-size,则使用默认值 12px */
color: var(--base-color, #ff4757); /* 如果没有设置 --base-color,则使用默认值 #ff4757 */
box-shadow: var(--base-shadow);
background-color: var(--base-bg-color, rgba(255, 71, 87,0.1)); /* 如果没有设置 --base-bg-color,则使用默认值 rgba(255, 71, 87,0.1) */
}
</style>
font-size 和 color 的值都有定义,所以会使用的定义的值,而 background-color 没有定义,所以会使用默认值。效果:

变量覆盖
有时候可能我们不想要默认的变量值,而是需要特殊设定。比如某些三方组件里面使用 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
<link rel="stylesheet" href="./a.css">
<link rel="stylesheet" href="./b.css">
<div class="box">
box1 中的文字内容
</div>
<div class="box">
box2 中的文字内容
</div>
效果:

b.css 在 a.css 之前引入示例:
html
<link rel="stylesheet" href="./b.css">
<link rel="stylesheet" href="./a.css">
<div class="box">
box1 中的文字内容
</div>
<div class="box">
box2 中的文字内容
</div>
效果:

由于变量的覆盖特性,所以不建议到处声明变量,应该集中管理,在固定文件中声明 CSS 变量!!
主题换肤
一个简单的换肤示例:
html
<div class="box">
box 中的文字内容
</div>
<div>
<!-- 点击事件将 body class 置空 -->
<a href="javascript:;" onclick="document.body.className = ''">无主题</a>
<!-- 点击事件给 body 添加 class -->
<a href="javascript:;" onclick="document.body.className = 'theme-1'">主题1</a>
<!-- 点击事件给 body 添加 class -->
<a href="javascript:;" onclick="document.body.className = 'theme-2'">主题2</a>
</div>
<style>
.theme-1 {
--base-font-size: 24px;
--base-color: #333;
--base-shadow: 0 0 0 6px rgba(0, 0, 0, 0.3);
--base-bg-color: rgba(71, 163, 255, 0.1);
--base-border: 2px solid rgba(71, 163, 255,0.3);
}
.theme-2 {
--base-font-size: 18px;
--base-color: #333;
--base-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
--base-bg-color: rgba(255, 197, 71, 0.1);
--base-border: 2px solid rgba(255, 197, 71,0.3);
}
.box {
margin: 20px 0;
width: 400px;
height: 120px;
border: var(--base-border, 2px solid rgba(255, 71, 87,0.3));
font-size: var(--base-font-size, 16px);
color: var(--base-color, #ff4757);
box-shadow: var(--base-shadow, 3px 3px 6px rgba(0, 0, 0, 0.3));
background-color: var(--base-bg-color, rgba(255, 71, 87,0.1));
}
</style>
效果:

写在最后
CSS 变量可以让我们很方便的进行主题换肤,也让前端可以集中管理重复的颜色、字体、边框等属性,增强了代码的可维护性。