一、简述
CSS 变量(CSS Variables),也称作 CSS 自定义属性(CSS Custom Properties),它是带有前缀 -- 属性名,且带有值的自定义属性。然后通过var 函数在全文范围复用。
至于为什么采用--,大概是因为@ 被Less 占用了,$ 被Sass 占用了吧。
1.1 语法
定义 CSS 变量的语法非常简单,在变量名称之前添加两个短横线 --:
--:
其中 表示变量名称, 表示变量值,形如:--*。这类自定义 CSS 属性与 color、font-size、background-image 等属性并没有什么不同,只是它没有默认含义罢了,它必须通过var() 函数复用之后,才会产生意义。
其中「变量名称」命名约束是比较宽松的,可以是数字、字母、下划线_、短横线- 的组合,但不能包含$、[、^、(、% 等字符。比如:
--some-keyword: left;--some-color: #f00;--some-complex-value: 3px 6px rgb(20, 32, 54);
甚至可以是以数字开头、也可以是中文、韩文等。
:root {
--红色: #f00; /* 有效 */
--1: 1px; /* 有效 */}
body {
background-color: var(--红色);
height: var(--1);}
当然,实际项目中,千万别以这种花里胡哨、奇奇怪怪的组合来命名变量名称,主要是避免被打。建议使用kebab-case 方式进行命名,比如--theme-primary 等。
请注意,CSS 变量名称是大小写敏感的,--foo 和--Foo 是两个不同的变量。这一点与CSS 属性大小写不敏感是有区别的。
1.2 作用域
同一个 CSS 变量,可以在多个选择器内声明,读取顺序与 CSS 匹配规则一致,优先级最高的生效。请注意,CSS 变量并没有 !important 用法,变量的覆盖规则由 CSS 选择器权重决定。
一般情况下,全局性变量放在:root 内声明,也可以在任意元素中声明 CSS 变量,视实际情况而定即可。如果是小程序,则在全局样式 app.wxss 的page 内声明。
:root 这个CSS 伪类匹配文档树的根元素。对于HTML 来说,:root 表示 元素,除了优先级更高之外,与html 选择器相同。
:root {
--theme-primary: #f00; /* 全局可复用 */}
header {
--theme-primary: #0f0; /* 仅 header 范围内可复用 */}
section {
--theme-primary: #00f; /* 仅 section 范围内可复用 */}
比如
内使用color: var(--theme-primary),生效的将会是color: #00f。再者,以下示例中,在 中引用--color 变量,最终生效的是 ID 选择器的变量值。:root {
--color: #f00;}
div {
--color: #0f0;}
#id {
--color: #00f;}
总的来讲,CSS 变量是有作用域概念的,它只能作用于自身或后代元素,而兄弟元素、祖先元素都是不用享用的。
可以试下这个示例:css-variable-scope-demo。
1.3 兼容性
兼容性如下,还是挺不错的(如果忽略 IE 的话),更多请看 Can I use。
对于不支持 CSS 变量的浏览器,可以采用如下方式兼容处理:
:root {
--color-primary: #00f;}
a {
color: #00f;
color: var(--color-primary);}
也可以使用@supports 规则,然而它也不兼容 IE 浏览器。
@supports (--foo: 0) {
/* supported */}
@supports (not (--foo: 0)) {
/* unsupported */}
二、JavaScript 操作
利用CSS.supports() 方法即可判断当前浏览器是否支持 CSS 变量,如下:
const isSupported = window.CSS.supports('--foo', 0)
由于 CSS 变量就是自定义的 CSS 属性嘛,因此按照平常设置 CSS 属性的方式去操作即可,如下:
const element = document.querySelector('selectors')
// 定义 CSS 变量
element.style.setProperty('--color', '#f00')
// 读取 CSS 变量
element.style.getPropertyValue('--color', '#f00')
// 删除 CSS 变量
element.style.removeProperty('--color')
另外有一个比较奇怪的用法(来自EXAMPLE 7),如下:
:root {
--foo: if(x > 5) this.width = 10;}
尽管这个属性值是「无用」的,不会使得任意 CSS 属性产生实际效果,但是这个 CSS 变量定义是「有效」的。它可以被 JavaScript 读取,至于有什么用,我也不知道。