css 变量
- 又称为 CSS 自定义属性,它的值可以在整个文档中重复使用。
- 设定值
--
双横线 - 获取值
var()
函数
变量的声明与使用
因为 $
被 Sass 用掉了,@
被 Less 用掉了 ,为了不产生冲突,官方的 CSS 变量就用了--
。
声明变量的时候,变量名前面要加两根连词线--
。
body {
// 声明
--font-color: #7F583F;
}
.main{
// 使用
color:var(--font-color);
}
css变量命名规则
- 普通字符局限在只要是 数字
[0-9]
字母[a-zA-Z]
下划线_
和 短横线-
这些组合,可以是中文
,日文
或者韩文
- 不能包含特殊字符:
$ , [ ,^, ( ,%
等字符 - 变量名大小写敏感,
--header-color
和--header-Color
是两个不同变量
body {
--深蓝: #336699;
background-color: var(--深蓝);
}
变量值只能用作属性值,不能用作属性名
.foo {
--side: margin-top;
/* 无效 */
var(--side): 20px;
}
变量的定义和使用只能在声明块{}
里面, 例如,下面这样是无效的:
--深蓝: #336699;
body {
background-color: var(--深蓝);
}
var()函数的第二个参数,表示变量的默认值。如果该变量未定义,就会使用这个默认值。
body {
color: var(--foo, #7F583F);
}
第二个参数不处理内部的逗号或空格,都视作参数的一部分。
body {
// "Roboto", "Helvetica" 整体是默认值
var(--font-stack, "Roboto", "Helvetica");
// 10px 15px 20px 整体是默认值
var(--pad, 10px 15px 20px);
}
变量值的类型
如果变量值是数值,不能与数值单位直接连用。
.foo {
--gap: 20;
/* 无效 */
padding: var(--gap)px;
/* 有效 */
font-size: calc(var(--gap) * 1px); //20px
}
变量值多属性可以拼接。
body{
--width: 1px;
--type: solid;
--foo: var(--width) var(--type) #000000;
}
对于CSS变量,只要语法是正确的,就算变量里面的值是个乱七八糟的东西,也是会作为正常的声明解析,
如果发现变量值是不合法的,例如下面案例font-size
显然不能是#ddd
,则无css展示效果,或用本身该属性的默认值。
body {
--size: #ddd;
font-size: 30px; // 无作用 被下面的覆盖
font-size: var(--size); // 变量值不合法 继承上级
}
作用域
- 同一个 CSS 变量,可以在多个选择器内声明。
- 读取的时候,优先级最高的声明生效
- 变量的作用域就是它所在的选择器的有效范围。
优先级别:内联样式 > ID选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 = 伪元素选择器
<style>
:root { --color: blue; } //根元素 :root 代表全局参数
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
</style>
<p>蓝色</p>
<div>绿色</div>
<div id="alert">红色</div>
JavaScript 操作
- CSS 变量提供了 JavaScript 与 CSS 通信的一种途径
// 设置变量
document.body.style.setProperty('--primary', '#7F583F');
// 读取变量
document.body.style.getPropertyValue('--primary').trim();
// '#7F583F'
// 删除变量
document.body.style.removeProperty('--primary');
设置伪元素
<div class="box" style=" --theme-secondary-color:red ">I am Child 2</div>
//优点 可以直接设置伪元素
div::after {
color: var(--theme-secondary-color);
}
在vue2 中 使用
<template>
<div class="hello" :style="styleVar">
<div class="child-1">I am Child 1</div> //blue 30px
<div class="child-2">I am Child 2</div> //red 30px onclick => red 40px
<div @click="onClick">ChangeSize</div>
</div>
</template>
<script>
export default {
data() {
return {
styleVar: {
"--colorBlue": "blue",
"--colorRed": "red",
"--fontSize": "30px",
"--fontSizeTest": "30px",
},
};
},
methods: {
onClick() {
// 改变data 的属性值 style中 css 获取到的变量更新
this.styleVar["--fontSizeTest"] = "40px";
},
},
};
</script>
<style scoped>
.child-1 {
color: var(--colorBlue);
font-size: var(--fontSize);
}
.child-2 {
color: var(--colorRed);
font-size: var(--fontSizeTest);
}
</style>
vue3 中优化后
在 Vue 3 中,style 标签支持 vars 绑定,该参数接受对象键值对方式注入 CSS 变量,
这些变量会直接绑定到组件的根元素上
<template>
<div class="content">
<div class="text">hello</div>
<div>
</template>
<script>
export default {
data() {
return {
color: "red",
};
},
};
</script>
<style vars="{ color }">
.text {
color: var(--color);
}
</style>
<div style="--color:red" class="content" >
<div class="text"> hello </div> // color =>red
<div>
- 和
<style scoped>
一起使用
所应用的 CSS 变量将以组件的 Scoped id 作为前缀,访问的时候也会自动加上 Scoped id
<style scoped vars="{ color }">
h1 {
color: var(--color);
}
</style>
编译之后
h1 {
color: var(--6b53742-color);
}
假如 想访问的是全局的 CSS 变量呢?也就是我们不希望加上 Scoped Id,那么要加global
:
<style scoped vars="{ color }">
h1 {
color: var(--color);
font-size: var(--global:fontSize);
}
</style>
编译之后
h1 {
color: var(--6b53742-color);
font-size: var(--fontSize);
}
在react中使用
- react中使用也是相同的模式
const [color,setColor]=useState('red')
<div className="guide-page " style={{'--color':color}}>
<p className="guide-intro">
测试引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。本 Demo 是基于driver.js.
</p>
</div>
.guide-page {
.guide-intro {
color: var(--color);
}
}
浏览器兼容性问题
CSS 变量目前的支持度并非特别好,IE 目前全部都是不支持的