【墨夜拎月 · web2.0 · css】CSS 变量

179 阅读3分钟

一、简述

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-vars-ponyfill

对于不支持 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 读取,至于有什么用,我也不知道。