CSS 变量, 很像任何其它一种编程语言里的变量, 可以让我们对一个值进行反复的引用. 始自 2017 年 4 月, 所有的现代浏览器 http://caniuse.com/#feat=css-variables 都支持了这个功能, 使得我们能编写出更紧凑, 更清晰的 CSS 样式.
下面我将要介绍一下 CSS 变量的基本概念和用法, 讲讲它和 Sass 变量的不同之处, 以及如何兼容老 CSS,Sass 代码.
如何使用 CSS 变量
任何 CSS 属性 color, size, position 等都可以存放在 CSS 变量里. CSS 变量的名称必须是以 -- 为前缀, 它们的声明和定义跟普通的 CSS 样式定义一样:
- body {
- --primary: #7F583F;
- --secondary: #F7EFD2;
- }
在其它 CSS 代码中引用这个变量需要使用 var()方法.
- a {
- color: var(--primary);
- text-decoration-color: var(--secondary);
- }
如果你用 firebug 在浏览器里观察这些变量的使用, 会发现被引用的变量并没有显示成它真实的值, 仍然显示的是变量.
这个 var()方法实际上可以有两个参数, 第一个参数是需要引用的变量, 而第二个参数是可选的, 作用是如果这个变量没有找到时使用的替代值.
color: var(--primary, #7F583F);
"没有找到" 的原因有可能是没有定义, 或者是, 定义了, 但不在有效作用域内.
CSS 变量的作用域
CSS 变量的作用域和普通的样式属性是一样的. 变量的作用范围是联级向下渗透的. 比如, 下面这个变量将会在整个页面生效.
- body {
- --primary: #7F583F;
- --secondary: #F7EFD2;
- }
而在一个 CSS 规则内定义的变量只会在这个规则内有效:
- .content {
- --primary: #7F583F;
- --secondary: #F7EFD2;
- }
如果你在. content 之外的地方引用这个变量, 将不会有任何效果.
CSS 变量和自定义属性
可以看出, CSS 变量和普通的 CSS 属性的作用是类似的, 声明变量, 定义变量值, 引用它们.
其实它们就是自定义 CSS 属性, 唯一 --primary 和 position 不同之处是, position 是静态值, 立即生效的, 而 --primary 是需要引用才能生效的.
浏览器对 CSS 变量的支持意味着, 开发人员可以定义任意的 CSS 属性. 这绝对是一个令人兴奋的事情, 它的意义就如同 CSS 媒体查询 (media queries) 功能的出现, 彻底的让开发人员摆脱了用 JavaScript 监听器来监听浏览器窗口大小的变化. CSS 变量开启了一个新的通道, 让我们不再依赖 JS 和 CSS 预处理器.
CSS 变量比较 Sass 变量: 切换主题颜色
CSS 变量和 Sass 变量不同, 在某些方面, CSS 变量比 Sass 变量更好用. 比如, 设计网站的主题色调. 使用 Sass 也很容易实现这个, 比如定义不同的颜色存放在 Sass maps 里, 循环它们, 生成各种不同的 classes:
- .theme-1 {
- a {
- color: #7F583F;
- text-decoration-color: #F7EFD2;
- }
- }
- .theme-2 {
- a {
- color: #D51522;
- text-decoration-color: #F4F6D8;
- }
- }
- /* etc */
CSS 代码容易生成, 但有多少种颜色我们就需要生成多少个 class. 同时只有一个能用到.
而使用 CSS 变量, 我们可以使用 JavaScript 来控制变量的值:
- document.body.style.setProperty('--primary', '#7F583F');
- document.body.style.setProperty('--secondary', '#F7EFD2');
只需要改动一个值, 整个页面的引用了这个变量的地方的颜色都会发送变化, 代码变得简介干净.
CSS 变量比较 Sass 变量: 媒体查询 media queries
在 Sass 里, 变量在 media queries 无法重新定义的. 比如, 你希望在不同的媒体查询条件里定义不同的颜色变量, 如下:
- $primary: #7F583F;
- $secondary: #F7EFD2;
- a {
- color: $primary;
- text-decoration-color: $secondary;
- @media screen and (min-width: 768px) {
- $primary: #F7EFD2;
- $secondary: #7F583F;
- }
- }
很可惜, 这种写法在 Sass 里是无效的, 因为 Sass 是一个预处理工具, 无法知道这些媒体查询条件真正执行是的样子. 此时, 如果使用 CSS 变量:
- body {
- --primary: #7F583F;
- --secondary: #F7EFD2;
- }
- a {
- color: var(--primary);
- text-decoration-color: var(--secondary);
- }
- @media screen and (min-width: 768px) {
- body {
- --primary: #F7EFD2;
- --secondary: #7F583F;
- }
- }
这种写法是可以正确的执行, 因为变量的引用是在浏览器里发生的, 浏览器知道什么时候该引用哪个变量.
浏览器对 CSS 变量的支持情况
火狐浏览器从 2014 年就开始支持 CSS 变量了, 而谷歌浏览器和 Safari 是从 2016 年 3 月开始支持的, 落后的 Edge 浏览器最终也在 2017 年 4 月支持了 CSS 变量!(Source: CanIUse http://caniuse.com/#feat=css-variables .)所以, 可以说, 使用 CSS 变量是比较安全的. 而如果你的 CSS 代码想兼容老的 IE 浏览器, 请看下面的兼容补救方法.
如何兼容老式浏览器
其实很简单:
- a {
- color: #7F583F;
- color: var(--primary);
- }
首先声明备用属性, 然后定义 CSS 变量, 支持 CSS 变量的浏览器会使用后者, 而不认识 CSS 变量的浏览器会使用前者.
如何在 Sass 兼容老式浏览器
如果你使用的是 Sass, 可以通过一个 Sass mixmin 来自动达到兼容的目的.
- $vars: (
- primary: #7F583F,
- );
- body {
- --primary: map-get($vars, primary);
- }
- @mixin var($property, $varName) {
- #{$property}: map-get($vars, $varName);
- #{$property}: var(--#{$varName}, map-get($vars, $varName));
- }
这样使用它:
- a {
- @include var(color, primary);
- }
输出的 CSS 代码是这样的:
- a {
- color: #7F583F;
- color: var(--primary, #7F583F);
- }
这样, 如果我们想修改 --primary 或 备用值, 只需要编辑 $vars,CSS 的其它地方都会跟着变化.
来源: http://www.webhek.com/post/css-variables-and-sass-variables.html