关于CSS变量你需要知道的一切都在这里
这是我新书的第一章(PDF和Mobi格式都有)。
多数编程语言都支持变量。但是CSS从最初就一直缺少对原生变量的功能支持。
你写CSS吧?那你就没办法用变量。不过,你还可以用Sass这样的预编译器。
Sass这样的预编译器就把变量作为一个巨大的卖点,一个尝试新东西的原因。你知道吗?我们还真的很吃这一套。
不过互联网还在飞速前行。所以我也很开心的宣布CSS现在终于支持变量了。
预编译器支持更多的特性,其中CSS变量就是一个不错的卖点。这些工作让互联网更加接近未来。
在这篇指南里,我会展示如何使用CSS原生变量,以及如何在日常工作里使用它们,让生活变的更美好。
你会学到这些
首先,我会介绍一些CSS变量的基础知识。我相信理解CSS变量应该从这里开始。
学习基础知识是非常酷的一件事。更酷的把这些基础知识应用到现实应用当中去。
所以我会用三个例子来展示如何方便的使用CSS变量。下面我们简单过一下这三个例子。
例1:使用CSS变量创建可变组件
今天你可能已经在构建自己可变组件了。无论你是在使用React,Angular,或者Vue,CSS变量都能使这个过程简洁许多。
使用CSS变量创建可变化的组件
参见 Codepen的这个例子
例2: 带有CSS变量的主题样式
你可能已经在别处看到过这样的用法。我接下来要展示的是CSS变量如何使得创建站点级别的主题样式更加简便。
使用CSS变量的网站级别主题样式
参见 Codepen的这个例子
例3: 创建CSS变量盒?
恩,这是最后一个例子。请忽略这个名字,我想不到更好的了…
这些盒子的颜色是可以动态更新的。
注意这些盒子的颜色是动态更新的,盒子容器也是可以3D旋转的。
这个例子让我们看到如何使用JavaScript更新CSS变量,并展示出一个很好的交互效果。
接下来的更有趣!
花点时间尝试一下 Codepen上的这个例子。
为何变量如此重要
如果你刚开始学预编译器的变量,或者熟悉原生CSS,下面便是一些你要了解变量的原因:
原因1:提高代码可读性
无需赘言,变量让代码可读性更强,可维护性更好。
原因2: 使大型文档中的代码改动更容易
如果你所有的常量都存在一个单独的文件里,你就不需要在几千行代码里一一修改变量了。这就很容易了。 只要改一行,就结了!
原因3: 更快的发现拼写错误
在多行代码里找错,是很痛苦的一件事。更烦人的是,这个错误可能只是简单的拼写错误。很难查找。合理使用变量,就能消除一些烦心事。
因此,可读性和可维护性可以双赢。
感谢CSS变量,现在我们终于可以在原生CSS中使用它们了。
定义CSS变量
让我们从你熟悉的开始吧:JavaScript中的变量。
一个JavaScript中的变量可能是这样定义的:
var amAwesome;
然后这样赋值:
amAwesome = "awesome string"
CSS中,一个CSS变量是任意一个以两个破折号开头的”属性“值,
/*能找到这里定义变量么? */
.block {
color: #8cacea;
--color: blue
}
CSS变量也称作”自定义属性“
CSS变量作用域
还有一点你需要注意。
在JavaScript里,变量都有一个作用域。它们或是一个全局变量,或是一个局部变量。
CSS变量也一样。请看下面的例子:
:root {
--main-color: red
}
:root
选择器能让我们选择DOM树里的最顶级的元素,也就是文档树。所以,这样定义的变量,也就相当于全局变量了。理解了么?
如何在局部和全局范围内定义变量
例1
假设你想设置一个存储网站主题样式的CSS变量,你会怎么做?
- 你需要使用范围选择器。用
:root
来定义一个全局变量。:root { }
- 定义变量
:root { --primary-color: red }
请记住,CSS变量是任意一个以两个破折号开始的“属性”。就这么简单。
使用CSS变量
变量定义且被赋值后,你就可以使用它了。不过要上手还是有一些麻烦的地方。
如果你习惯了预编译器,那么肯定知道如何使用变量了。例如:
$font-size: 20px
.test {
font-size: $font-size
}
CSS变量和这稍有不同。 你需要使用var()
这个函数引用变量。
上面的例子中,CSS变量是这样引用的:
:root {
--font-size: 20px
}
.test {
font-size: var(--font-size)
}
非常不同。
请记住使用var()
函数
一旦你习惯了这样的方式,你就会爱上CSS变量的,非常爱!
另一个重要的提示是,不像Sass或者其他预编译器中的变量,你可以在很多地方使用变量。CSS的变量需要小心谨慎,如果需要你还能做数学运算。多数情况下你应该把它们当作属性值来使用。
/*下面这样是不对的*/
.margin {
--side: margin-top;
var(--side): 20px;
}
这样定义会抛出无效属性名的语法错误
你也无法直接使用数学运算功能。运算功能需要使用 calc()
函数。后面遇到时我会加以讨论。
/*下面这样也不对 */
.margin {
--space: 20px * 2;
font-size: var(--space); //这不是 40px
}
如果你一定需要用数学计算,那么请使用 calc()
函数,如下:
.margin {
--space: calc(20px * 2);
font-size: var(--space); /*equals 40px*/
}
值得一提的属性
有一些行为是值得提醒注意的。
1. 自定义属性是普通属性值,因此它们可以定义在任意元素上。
在段落p元素,section,aside元素或者root根元素,甚至是伪元素上使用变量,都是可以的。
它们和普通属性一样工作
2. CSS变量和普通CSS继承和叠加的规则相同
看这个例子:
div {
--color: red;
}
div.test {
color: var(--color)
}
div.ew {
color: var(--color)
}
和普通变量相同,--color
的值也会从其他的div元素继承下来。
3. CSS变量也可以和 @media
或其他条件选择的规则同时使用
和其他属性一样,你也可以使用@media
或其他的条件规则里使用变量,
例如,下面的代码改变了变量的值,在不同的设备上使用不同值。
:root {
--gutter: 10px
}
@media screen and (min-width: 768px) {
--gutter: 30px
}
适合用在自适应的设计中
4. CSS变量可以在HTML的style属性中使用
你也可以在内联样式里使用变量,它们也正常工作。
<html style="--color: red">
body {
color: var(--color)
}
设置inline变量
CSS变量大小写敏感。请注意这一点。我为了省事全部都用小写。你的情况可能不一样。
/*这是两个不同的变量*/
:root {
--color: blue;
--COLOR: red;
}
解决多重定义
和其他属性是一样的,重定义变量也遵循标准级联规则。
下面来看个例子:
/*变量定义*/
:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
/*使用变量 */
* { color: var(--color); }
有了上面的定义,不同元素的值是什么样的呢?
<p>我的颜色是?</p>
<div>我的呢?</div>
<div>
我的颜色是?
<p>颜色?</p>
</div>
你能猜出来么?
第一个p元素是 blue
,没有任何--color
变量定义是在 p
元素的,因此它会继承自根元素 :root
。
:root { --color: blue; }
第一个div
是绿色green。毋庸赘述。在
div`上有一个颜色变量定义。
div { --color: green; }
使用ID值为alert
定义的 div
,不是绿色,而是红色red
。
#alert { --color: red; }
The ID has a direct variable scoping. As such, the value within the definition will override the others. The selector #alert
is more specific. 这个ID有一个更直接的变量范围。因此,这个范围内定义的变量值会覆盖其他的变量值。#alert
ID选择器更具体。
最后, 在ID#alert
中的这个p
是红色red
。
在第一个p
元素上,并没有变量声明。可以推测,这个元素是在根元素 :root
以内的,因此它的颜色是蓝色。
:root { --color: blue; }
和其他属性一样,CSS变量也是可继承的。这个值也会从其父节点上获得。
#alert { --color: red; }
谜语的答案
解决循环依赖
循环依赖通常会在下面几种情况下发生:
- 变量需要依赖其自身值。也就是说,定义时就使用了
var()
引用其值。
:root {
--m: var(--m)
}
body {
margin: var(--m)
}
- 多个变量相互引用时。
:root {
--one: calc(var(--two) + 10px);
--two: calc(var(--one) - 10px);
}
请注意,不要在代码中创建这样的循环引用。
使用无效变量会怎样?
语法错误会被忽略,但是无效的使用 var()
会导致错误的初始值或者是继承到有问题的值。
看下面的代码:
:root { --color: 20px; }
p { background-color: red; }
p { background-color: var(--color); }
--color
会被代入var()
,但是这条属性值,background-color: 20px
在变量代入后是无效的(译者注:错误的颜色值)。因为backgroud-color
不是继承属性,那么它的值就会是这个属性的初始值 transparent
。
请注意,如果你直接写backgroud-color: 20px
,那么这个属性声明就是无效的。这一行之前的定义就正常工作了。
如果你直接这样写变量声明那情况就不一样
创建单一标记时,请注意
当你设置一个类似下面的属性的变量时,20px
就被编译成一个单一标记。
font-size: 20px
简单理解就是,20px
就是一个单独的整体。
使用CSS变量构建独立单一标记需要十分小心。
例如,看下面的代码:
:root {
--size: 20
}
div {
font-size: var(--size)px **/*错了*/**
}
你也许会认为,font-size
的值是20px
,但你错了。浏览器会解析成 20 px
, 注意20
和px
之间的空格。
因此,如果你一定需要创建独立标记,那么就一定要用变量表示这个整体。例如: --size: 20px
,或者是用 calc
这个函数,例如, calc(var(--size) * 1px)
,然后其中的--size
值就是20
。
不要着急。如果你还不太能理解这一点,后面的例子中我会解释的更具体。
一起来动手吧!
下面就是本文里我们最期待的一部分。
我会带着大家做一些有用的例子,把实际应用中的概念都过一遍。我们开始吧。
例1: 使用CSS变量创建可变组件
假设你需要创建两个不同的按钮。基本样式相同,只有一点小小的区别。
在这个例子里,不同的属性只有 background-color
和border-color
。
那怎样处理这种情况呢?下面是一种典型的解决方案:
创建一个基类,比如 .btn
,然后加上其他的不同类,例如:
<button class="btn">Hello</button>
<button class="btn red">Hello</button>
.btn
包含了按钮的基本样式,例如:
.btn {
padding: 2rem 4rem;
border: 2px solid black;
background: transparent;
font-size: 0.6em;
border-radius: 2px;
}
/*on hover */
.btn:hover {
cursor: pointer;
background: black;
color: white;
}
那按钮样式如何变化呢?像这样:
/* variations */
.btn.red {
border-color: red
}
.btn.red:hover {
background: red
}
你看,这里就有重复的代码了吧?这样也好,但使用CSS变量可以更简洁。
第一步是什么呢?
把变化的颜色值用CSS变量定义出来,不要忘记加默认值!
.btn {
padding: 2rem 4rem;
border: 2px solid var(--color, black);
background: transparent;
font-size: 0.6em;
border-radius: 2px;
}
/*on hover*/
.btn:hover {
cursor: pointer;
background: var(--color, black);
color: white;
}
你这样设置background: **var(--color, black)**
时,也就是说把背景设置为变量--color
的值。如果这个变量不存在,那就用默认值黑色**black**
替代 。
这就是设置默认值的方法,和JavaScript或者其他语言一样。
下面是有趣的部分了。
有了变量,你就可以像下面这样设置新的变量值了:
.btn.red {
--color: red
}
这就可以了。如果元素class中使用了.red
,那么浏览器就能注意到不同的--color
值,这样就使得不同的按钮有不同的颜色了。
这样你就可以省下来很多时间,创建可复用的组件了。
下图是简单的对比: 没有CSS变量和有CSS变量的情况
哦,对了,如果你有更多的变量,那还能省下很多打字的时间:
看到区别了么?
例2:使用CSS变量制作网站主题
我想你肯定遇到过这样的情况。有主题的网站可以让用户有自己定制的感觉,就像是由他们来控制一样。
下面这个例子就是我们要做的。
那么CSS变量是如何让这件事变得简单一点的呢?
让我们一起来看。
在这之前,我想提醒你,这个例子非常重要。在这个例子里,我会介绍如何使用JavaScript更新CSS变量。超有趣!你肯定会喜欢的。
我们实际要做的
CSS变量的美妙是它们的互动性。一旦它们的值发生了变化,对应CSS的属性也会相应的进行更新。
下图从概念上解释了在本例中这个过程是如何发生的 。
所以,我们需要增加一些JavaScript来监听点击事件。
在这个例子里,背景颜色和文字颜色是基于CSS变量的。
当你点击上面任何一个按钮时,它们就将对应的CSS变量设置成另一种颜色。于是,页面的背景颜色也更新了。
你看,这就是所有的内容了。
哦,还有一件事。
当我说把CSS变量设置成另一个值的时候,这又是怎样做到的呢?
把变量设置成inline
即便是设置在inline style中,CSS变量也会生效。和JavaScript一起,我们就可以控制整个root文档,这样也就能设置CSS变量的值了。
理解了么?
不过前面都是说的,下面我们来看代码。
初始代码
最初代码像这样:
<div class="theme">
<button value="dark">dark</button>
<button value="calm">calm</button>
<button value="light">light</button>
</div>
<article>
. . .
</article>
这段代码由三个button和一个 class是.theme
父元素组成。为了简洁一点我去掉了中间的内容部分,只用article
元素替代。article
元素内就是页面内容。
页面样式
这个小项目的成功点就是页面的样式。技巧其实很简单。
没必要为每种风格设置background-color
和 color
,我们只需要使用变量来设置即可。
就像下面这样:
body {
background-color: **var(--bg, white)**;
color: **var(--bg-text, black)**
}
这样做目的很明显。点击每个button时,这个页面的背景和文字颜色就可以随之变化。
基于这个改变,整体的页面就很容易改变了。小菜一碟。
接下来我们就来增加处理更新值的JavaScript脚本部分。
涉及JavaScript的部分
接下来我会把项目需要的JavaScript逐步分析。
const root = document.documentElement
const themeBtns = document.querySelectorAll('.theme > button')
themeBtns.forEach((btn) => {
btn.addEventListener('click', handleThemeUpdate)
})
function handleThemeUpdate(e) {
switch(e.target.value) {
case 'dark':
root.style.setProperty('--bg', 'black')
root.style.setProperty('--bg-text', 'white')
break
case 'calm':
root.style.setProperty('--bg', '#B3E5FC')
root.style.setProperty('--bg-text', '#37474F')
break
case 'light':
root.style.setProperty('--bg', 'white')
root.style.setProperty('--bg-text', 'black')
break
}
}
别被吓到了。代码其实比你想的简单的多。
首先,创建一个对root元素的引用, const root = document.documentElement
。
这里的root元素就是 HTML
。一会你就明白为什么这一点很重要了。如果你很好奇,就先理解这是为了设置CSS变量使用的。
然后,对不同button也保存对应的引用, const themeBtns = document.querySelectorAll('.theme > button')
。
querySelectorAll
会返回一个可以遍历的数组结构。这样我们就可以遍历每个按钮给它们增加对应的点击事件。
就像这样:
themeBtns.forEach((btn) => {
btn.addEventListener('click', handleThemeUpdate)
})
handleThemeUpdate
在哪呢?接下来就是。
点击按钮时,对应的handleThemeUpdate
就会触发。因此要记下哪个按钮点击了,应该执行对应什么样的操作。
因此,这里用了一个switch的 operator
,不同的按钮的点击事件在这里有了区别。
现在你再回去看一下前面的JavaScript的代码。你应该能更好的理解它了。
例3: 创建CSS变量盒?
假如你忘了,那再提一下,我们要做的例子是这样的:
请记住,盒子的颜色是动态变化的,盒子可以根据用户的输入进行3D的旋转。
你可以在Codepen上玩一下。
这是使用CSS变量和JavaScript共同创造出的一个即有交互性又很美妙的例子。
我们一起看看怎么做的。
代码片段
我们需要下面一些元素:
- 一个范围输入
- 一个容器来显示说明部分
- 一个部分用来列出不同的盒子和每一种输入
代码部分很简单,下面就是:
<main class="booth">
<aside class="slider">
<label>Move this ? </label>
<input class="booth-slider" type="range" min="-50" max="50" value="-50" step="5"/>
</aside>
<section class="color-boxes">
<div class="color-box" id="1"><input value="red"/></div>
<div class="color-box" id="2"><input/></div>
<div class="color-box" id="3"><input/></div>
<div class="color-box" id="4"><input/></div>
<div class="color-box" id="5"><input/></div>
<div class="color-box" id="6"><input/></div>
</section>
<footer class="instructions">
?? Move the slider<br/>
?? Write any color in the red boxes
</footer>
</main>
需要注意以下几点:
- 输入的范围是从
-50
到50
,步长是5
。而且,最小值是-50
。 - 如果你不太清楚这个范围输入是什么原理,可以在 w3schools找到相关说明。
- 注意外层带有
.color-boxes
类的容器,它包含了.color-box
的容器,再其中就是各种输入了。 - 或许应该提一下,第一个输入框的默认值是红色。
理解了页面的结构,接下来我们看一下页面样式。
- 首先把
.slider
和.instructions
的元素移出文档流,进行绝对定位。 - 然后给
body
元素添加日出的背景颜色,再用一朵花的背景图做装饰,放在页面的左下角。 - 然后把
color-boxes
居中对齐。 - 接下来给
color-boxes
增加样式。
我们一起来深入一下细节。下面的代码完成的是第一个任务。
/* Slider */
.slider,
.instructions {
position: absolute;
background: rgba(0,0,0,0.4);
padding: 1rem 2rem;
border-radius: 5px
}
.slider {
right: 10px;
top: 10px;
}
.slider > * {
display: block;
}
/* Instructions */
.instructions {
text-align: center;
bottom: 0;
background: initial;
color: black;
}
这段代码非常简单。我想你肯定能读懂,如果不懂就发评论或者发推。
给 body
元素加上样式就复杂一些了。希望你能很好的理解这部分CSS。
因为我们需要设置元素的背景颜色和背景图像,那么我们最好使用简化的background
属性来增加多种不同的背景。代码如下:
body {
margin: 0;
color: rgba(255,255,255,0.9);
background: url('https://bit.ly/2FiPrRA') 0 100%/340px no-repeat, var(--primary-color);
font-family: 'Shadows Into Light Two', cursive;
}
url
部分设置向日葵图片的链接。
接下来0 100%
代表图像在背景中的位置。
这里有对于CSS中background属性定位的具体阐释: 来源:the advanced guide to CSS
在斜线后的另一部分是代表 background-size
,这个值是340px
。如果这个值小一些,那图片也会更小一点。
你也许会想no-repeat
是什么意思,它意味着背景不允许重复。
最后,逗号之后的部分就是第二种背景声明。这次我们把background-color
设置成var(primary-color)
。
哦,它是一个变量。
这就意味着你需要定义这个变量,就像这样:
:root {
--primary-color: rgba(241,196,15 ,1)
}
现在的颜色是日出的黄色。不是什么大问题。接下来我们会设置更多的变量。
然后,把 color-boxes
居中对齐。
main.booth {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
主要容器是布局设置成flex,然后直接将子元素放在页面中间, 也就是接下来 color-box
的部分。
下面我们把容器和子元素美化一下。
首先是子元素:
.color-box {
padding: 1rem 3.5rem;
margin-bottom: 0.5rem;
border: 1px solid rgba(255,255,255,0.2);
border-radius: 0.3rem;
box-shadow: 10px 10px 30px rgba(0,0,0,0.4);
}
这样就够了。还加了一个漂亮的阴影。这样就有了酷炫的效果了。
不过这还不够。还有container-boxes
容器的样式:
/* Color Boxes */
.color-boxes {
background: var(--secondary-color);
box-shadow: 10px 10px 30px rgba(0,0,0,0.4);
border-radius: 0.3rem;
transform: perspective(500px) rotateY( calc(var(--slider) * 1deg));
transition: transform 0.3s
}
棒!
这样就好多了。
让我们细化一下。
下面是简单的部分:
.color-boxes {
background: **var(--secondary-color)**;
box-shadow: 10px 10px 30px rgba(0,0,0,0.4);
border-radius: 0.3rem;
}
你知道意思,对吧? 这里用了一个新的变量。因此我们需要在root选择器里加上定义。
:root {
--primary-color: rgba(241,196,15 ,1);
--secondary-color: red;
}
这里的secondary-color是红色。这样就使得容器有一个红色的背景。
但你可能对下面的部分感到疑惑,
/* Color Boxes */
.color-boxes {
transform: perspective(500px) rotateY( calc(var(--slider) * 1deg));
transition: transform 0.3s
}
我们可以暂时简化上面代码里transfrom的属性。
例如:
transform: perspective(500px) rotateY( 30deg);
transform合并了两个不同的函数。一个是透视,一个是以Y轴为标准的旋转。
不过,perspective
和 rotateY
又起了什么样的作用呢?
perspective()
函数可以使元素在3D的空间内变形。它会激活一个三维空间,使元素增加一个z轴。
你可以在 codrops看到更多关于perspective函数的介绍。
那么rotateY
函数又有什么用呢?
激活了三维空间后,元素就有了x,y,z三个轴。 rotateY
函数就意味着把元素以 Y
轴为中心进行旋转。
codrops的这幅图可以帮我们直观的理解这一点。
希望这能帮你拨开云雾见天日。
回到前面的主题。
移动滑块的时候,你知道是哪个函数影响了.container-box
的旋转效果么?
是的,就是这个 rotateY
函数被调用了。因此这个盒元素就沿着Y轴进行旋转。
因为这个值可以通过JavaScript传给函数,所以这个值就用一个变量来表示。
那为什么要用这个变量乘以1deg呢?
按通常的经验来说,也为了自由定义变量,我们建议在创建变量时,不带单位。
这样你就可以在任何需要使用单位的时候通过calc
函数达成目标。
这就使得你可以在需要时任意使用了。它即可以转化成deg
, 也可以转化成一个相对于用户视窗单位vw
的比例 ,你可以想怎么做就怎么做。
在这个例子中,我们把一个数字通过乘以一个1deg的值,得到了一个有单位的数值。
因为CSS并不理解数学计算,因此你需要把这个算术放在calc
函数里才能得到CSS属性需要的对应数值。
这些都完成,我们就可以开始下一步了。现在我们要用JavaScript来更新这个变量值。
不过还剩下一点CSS的代码。这就是了:
/* Handle colors for each color box */
.color-box:nth-child(1) {
background: var(--bg-1)
}
.color-box:nth-child(2) {
background: var(--bg-2)
}
.color-box:nth-child(3) {
background: var(--bg-3)
}
.color-box:nth-child(4) {
background: var(--bg-4)
}
.color-box:nth-child(5) {
background: var(--bg-5)
}
.color-box:nth-child(6) {
background: var(--bg-6)
}
这又是什么鬼?
首先,nth-child选择器用来选择不同的子元素。
这里我们需要看深入一点。我们已经了解需要更新每个盒子的颜色,也知道每盒子的颜色需要用一个变量以便使用JavaScript更新,对把?
因此,我们就这样设置:
.color-box:nth-child(1) {
background: var(--bg-1)
}
简单吧?
不过还有一个问题,如果这个变量不存在,那会怎么样呢?
我们需要默认值。
这样就没问题了:
.color-box:nth-child(1) {
background: var(--bg-1, red)
}
不过在这个实际的例子里,我选择不提供任何默认值。
如果这个变量的属性值不合法,那么这个属性值就会用其初始值。
也就是说,如果 --bg-1
不合法或者无效,那么背景就是它的初始值,也就是透明色。
没有明确指定时,初始值就是这个属性的默认值。例如,如果你不设置元素的 background-color
,那它就是默认就是透明的。
初始值也是一种默认值。
开始写JavaScript
需要写的JavaScript的部分非常少。
首先让我们处理滑块。
五行就够了!
const root = document.documentElement
const range = document.querySelector('.booth-slider')
//as slider range's value changes, do something
range.addEventListener('input', handleSlider)
function handleSlider (e) {
let value = e.target.value
root.style.setProperty('--slider', value)
}
很简单吧?
不过我还是要解释一下,以防我把你搞糊涂了。
首先,保存一个对slider元素的引用,const range = document.querySelector('.booth-slider')
。
然后给它增加一个事件,用来处理滑块值变化,range.addEventListener('input', handleSlider)
。
接下来就是这个回调事件handleSlider
:
function handleSlider (e) {
let value = e.target.value
root.style.setProperty('--slider', value)
}
root.style.setProperty('--slider', value)
是指把root
元素的style属性设置成对应值。
处理颜色变化
这和处理滑块值的变化一样简单。下面就是:
const inputs = document.querySelectorAll('.color-box > input')
//as the value in the input changes, do something.
inputs.forEach(input => {
input.addEventListener('input', handleInputChange)
})
function handleInputChange (e) {
let value = e.target.value
let inputId = e.target.parentNode.id
let inputBg = `--bg-${inputId}`
root.style.setProperty(inputBg, value)
}
保存一个对所有输入框的引用, const inputs = document.querySelectorAll('.color-box > input')
。
为每一个输入框增加一个事件处理:
inputs.forEach(input => {
input.addEventListener('input', handleInputChange)
})
接下来是 handleInputChange
函数:
function handleInputChange (e) {
let value = e.target.value
let inputId = e.target.parentNode.id
let inputBg = `--bg-${inputId}`
root.style.setProperty(inputBg, value)
}
嗯…
这就没了!
样例做完了!
我怎么能忘记这些呢?
我写完这篇文章还改了初稿之后,才想起来我还没提到浏览器的兼容性。所以,让我补上这一部分。
CSS变量的浏览器支持并不差。可以说相当好了,几乎所有的现代浏览器都能支持(我写这篇文章的时候超过87%)。 caniuse
所以,你可以在生产环境中使用么?我当然说是啦!不过你还是要检查一下适用的比例。
往好的方向面看,你也可以使用 Myth类似的预编译器。它可以把你现在使用的CSS变成未来可期的CSS,超酷的,对吧?
如果你有用过postCSS的经验,那这也是一个现在使用未来CSS的不错的方法。这里有一些使用postCSS的例子。
好啦,我都讲完了。
等等,我还有问题!
你可以在这本电子书里读到更多内容,还能拿到私人邀请,这样你就可以问我任何问题了。
挺公平的,不是吗?
下次再见!
via: https://medium.freecodecamp.org/everything-you-need-to-know-about-css-variables-c74d922ea855
作者: Ohans Emmanue 译者: Doraemonls
你也许感兴趣的:
- 【外评】电脑从哪里获取时间?
- 【外评】为什么 Stack Overflow 正在消失?
- Android 全力押注 Rust,Linux 却在原地踏步?谷歌:用 Rust 重写固件太简单了!
- 【外评】哪些开源项目被广泛使用,但仅由少数人维护?
- 【外评】好的重构与不好的重构
- C 语言老将从中作梗,Rust for Linux 项目内讧升级!核心维护者愤然离职:不受尊重、热情被消耗光
- 【外评】代码审查反模式
- 我受够了维护 AI 生成的代码
- 【外评】Linux 桌面市场份额升至 4.45
- 【外评】作为全栈开发人员如何跟上 AI/ML 的发展?
你对本文的反应是: