你应该掌握的CSS自定义属性技术点

编辑推荐:3月31日前,点击注册激活 Coding.net 立赠30天付费会员 ,体验极速代码托管服务!
特别声明:此篇文章内容来源于@Ohans Emmanuel的《Everything you need to know about CSS Variables》一文。
大多数编程语言都支持变量。但遗憾的是,CSS从一开始就缺乏对原生变量的支持。如果写CSS的话,那是没有变量的,除非你使用像Sass这样的CSS处理器。 变量是Sass这样处理器的一个非常有用的特性之一。这也是你尝试使用的理由之一。Web技术发展是非常快速的。我很高兴地告诉你,CSS现在终于支持原生的变量了。 虽然CSS处理器还支持更多的特性,但是CSS添加原生的变量是很好的。这些举措使用Web更接近未来的技术。在这篇文章接下来的内容中,我将向你展示如何在CSS使用变量,以及如何使用它们让你的工作变得更轻松。
特别声明:为了能让CSS的原生变量与CSS处理器变量区分出来,我更喜欢将其称为CSS自定义属性。

你将学到

首先会向大家介绍CSS自定义属性的基本知识。我相信试图理解CSS自定义属性都必须从这一点开始。学习CSS自定义属性的基本知识是非常有意思的事情。其中更有趣的是,你可以在真实的项目中使用这些基本原理。 因此,我将通过三个简单的项目来向你展示CSS自定义属性的易用性。先来快速预览一下这三个项目:

项目1:使用CSS自定义属性创建伟德1946手机版变量

你可能在项目中已经使用到了伟德1946手机版变量。不管是React、Angular或者Vue中,使用CSS自定义属性都会使这个过程变得更简单。

项目2:使用CSS自定义属性实现皮肤切换

你可能在某个地方看到过类似的效果。在这个项目中将向你展示使用CSS自定义属性是如何简单的为Web网站实现皮肤切换的效果。

项目3: 创建CSS自定义属性展台(Booth)

这是最后一个项目。请不要介意这个名字。说实在的,我想不出一个更好的名字了。
注意如何动态更新容器的颜色,以及如何在inputtype="range")控制条的范围内更改外部容器的3D旋转效果。 这个项目演示了使用JavaScript更新CSS自定义属性的便利性,以及即改即得的效果。你可以在上面示例中的input框中输入任意颜色值或者拖动range的进度条,浏览对应的效果变化。

为什么CSS自定义属性如此重要?

如果你是第一次接触CSS处理器中的变量或者CSS自定义属性,那么接下来介绍的几个方面将告诉你为什么CSS自定义属性对你而言是多么的重要。

理由1:代码更具可读性

不做过多的阐述,直接告诉你,使用CSS自定义属性可以让你的代码变得更具可读性和可维护性。

理由2:在大型项目中更易于修改

如果你将所有常量保存在一个单独的文件中,那么你想对一个变量进行更改时,不必跳过数千行代码。它变得很宽松,你可以把它放在任何一个地方。

理由3:更暴打发现输入错误

通过代码来查找错误是一件极为痛苦的事情。特别是你的错误是由于一个简单输入引起的,那就更令人恼火了。因为它是极难被人发现。CSS自定义属性的使用将消除这些麻烦。
为此,可读性和可维护性是CSS自定义属性最大的优势。
我们需要感谢 CSS自定义属性,让我们可以在CSS中使用原生的变量,而不再需要借助于类似Sass这样的CSS处理器。

定义CSS自定义属性

我们从一些熟悉的东西开始:JavaScript中的变量 一个简单的JavaScript变量可以像下面这样来声明: var amAwesome; 然后你可以给它赋值,比如: amAwesome = "awesome string" 在CSS中,一个CSS自定义属性是以两个破折号(--)开始的任何名称。 /* 你可以在这里声明一个CSS自定义属性*/ .block { color: #8cacea; --color: blue; /* 可以是常规的CSS属性,但需要以两个破折号(`--`)开始 */ }

CSS自定义属性作用域

还有一件事你需要注意。 请记住,在JavaScript中,变量是有作用域一说。它们可能是全局作用域,也有可能是局部作用域。那么在CSS中,CSS自定义属性也有这样的说法 比如下面这个示例: :root { --main-color: red } :root选择器可以选择到DOM元素中或document树中最高顶级的元素。因此,在:root选择器是声明的CSS自定义属性,其作用域的范围是全局范围,也就是全局作用域。 明白了? :root { --color: black; /* 全局作用域*/ } .block { color: #8cacea; --color: blue; /* 局部作用域;`--color`作用域是`.block`选择器 */ }

示例

假设你想创建一个CSS自定义属性,该自定义属性存储Web网站皮肤的主色(Primary color)。那么你将会怎么做呢? 你将创建选择器范围。使用:root创建一个global自定义属性: :root { } 然后声明自定义属性: :root { --primary-color: red; } 请记住,CSS自定义属性可以是任何名称,但名称前必须要以两个破折号,比如--color 这是不是很简单。

使用CSS自定义属性

一旦声明了一个CSS自定义属性,并给其指定了一个值,那么你就可以在CSS的属性值中使用它。不过使用还是有点小问题。 如果你是在CSS处理器中使用,那么你必须在属性值中引用这个已声明的变量,例如: $font-size: 20px; .test { font-size: $font-size; } 但在CSS中使用已声明的CSS自定义属性,和在CSS处理器中使用声明的变量略有不同。你需要通过var()函数来引用已声明的CSS自定义属性。 比如上面的示例,在CSS中使用已声明的CSS自定义属性,需要像下面这样使用: :root { --font-size: 20px; /* 声明一个全局使用域的CSS自定义属性 */ } .test { font-size: var(--font-size); /* 通过var()函数调用已声明的CSS自定义属性--font-size */ } 一旦你理解了这一点,你就会开始喜欢CSS自定义属性,而且会很喜欢。 不过需要特别注意的是,CSS自定义属性不像Sass(或其他CSS处理器)中的变量,可以在许多地方使用变量,并且可以进行一些数学运算,但使用CSS自定义属性时,只能在CSS属性值中使用CSS自定义属性 /* 这是一种错误的使用方式 */ .margin { --side: margin-top; var(--size): 20px; } 也不能像Sass这样的处理器一样直接做一些数学计算。如果你需要做一些数据计算,需要使用CSS的calc()函数。我们将在后续的示例中会聊到这一点。 /* 这是一种错误的使用方式 */ .margin { --space: 20px * 2; font-size: var(--space); } 使用CSS自定义属性要做一些数学计算时,应该像下面这样通过calc()函数来完成: .margin { --space: calc(20px * 2); font-size: var(--space); }

值得注意的地方

以下几个点是值得一提的地方。

自定义属性是普通属性,可以在任意元素上声明它们

CSS自定义属性可以在任意元素上,比如psectionaside、根元素,甚至是伪元素上声明。他们都会按照预期进行工作。 p { --color: blue; } section { --color: #bad; } aside { --color: yellow; } :root { --color: teal; } p:before { --color: red; } 当你在对应的元素中调用相应的CSS自定义属性时,可以看到他们都能按照你的预期工作:

CSS自定义属性可以通过继承和级联规则来解决

比如下面这段示例代码: div { --color: red; } div.test { color: var(--color) } div.ew { color: var(--color) } 和正常变量一样,--color将会继承div中的值: CSS自定义属性

CSS自定义属性可以通过@media和其他条件规则来实现

和其他属性一样,可以在@media其他条件规则中更改CSS自定义属性的值。 比如下面这段示例代码,在较大的屏幕设备上将会改变gutter的值: :root { --gutter: 10px; } @media screen and (min-width: 768px) { --gutter: 30px; } CSS自定义属性

CSS自定义属性可以用在HTML元素的style属性中

你可以选择在内联样式中声明CSS自定义属性,它同样是可以按照你的预期进行工作。 <!--HTML--> <html style="--color: red"> <!--CSS--> body { color: var(--color) }
值得一提的是:CSS自定义属性是区分大小写的。这一点需要特别的注意。
/* 这是两个不同的CSS自定义属性 */ :root { --color: blue; --COLOR: red; }

解决多个声明的CSS自定义属性

CSS自定义属性和其他CSS属性一样,可以用标准级联解决多个相同声明的CSS自定义属性。比如下面这个示例: /* 声明相同名称的CSS自定义属性 */ :root { --color: blue; } div { --color: green; } #alert { --color: red; } /* 使用CSS自定义属性 */ * { color: var(--color); } 就上面声明的CSS自定义属性,下列元素的文本颜色将会是什么颜色呢? <p>What's my color?</p> <div>and me?</div> <div id='alert'> What's my color too? <p>color?</p> </div> 你能基于上述的知识点猜出来结果吗? 第一个<p>元素是blue。因为在p选择器上没有显式定义--color,所以它将继承来自:root中的--color的值。 :root { --color: blue; } 第一个<div>元素将是green。这一点非常的明显,因为在div选择器上显示的声明了--color自定义属性的值为green div { --color: green; } ID名为#alertdiv元素,它的颜色不再是green,将会是red,那是因为在#alert选择器中也显式的声明了--color的值为red: #alert { --color: red; } 该ID选择器直接声明了一个自定义属性的作用域,其定义的值将会覆盖前面div声明的自定义属性,那是因为#alert选择器的权重高于div选择器。 由于最后一个<p>元素在#alert内,所以它的颜色也将是red p元素上没有显式声明CSS自定义属性,但在:root元素上显式的声明了,因为正如你所期望的一样,其颜色为blue :root { --color: blue; } 但CSS自定义属性和CSS中的其他属性是类似的,也具有继承这样的特性。所以最后一个<p>元素会继承其父元素#alert中声明的CSS自定义属性值: #alert { --color: red; } CSS自定义属性

解决循环依赖

循环依赖的发生方式如下。 当一个变量依赖于它自己。也就是说,它使用的是引用自身的var() :root { --m: var(--m) } body { margin: var(--m) } 另外一种方式就是两个或多个变量相互引用时: :root { --one: calc(var(--two) + 10px); --two: calc(var(--one) - 10px); } 目前唯一可破的方法是:不要在代码中创建具有循环依赖关系的CSS自定义属性

无效的CSS自定义属性将会发生什么?

如果是语法错误,将会直接视为无效,但无效的var()将会被该属性的初始值或继承值替代。比如下面的示例: :root { --color: 20px; } p { background-color: red; } p { background-color: var(--color); /* 设置了一个无效的颜色值 */ } 如你所预期的一样,--colorvar()替换了,但是属性值background-color:20px是一个无效值。由于background-color不是一个可继承的属性,所以该值将默认为background-color的初值值transparent CSS自定义属性 请注意,如果你已经写了background-color: 20px没有自定认属性来替换,那么background-clor将是无效的。要是前面有对应的声明,将会使用前面的声明。

在构建单个指令时要小心

当你设置如下所示的属性值时,20px被解释为单个指令(Tokens)。 font-size: 20px 一个简单的方法是,20px的值被视为一个单独的实体。在使用CSS自定义属性构建单个指令时,需要特别的小心。比如下面这段示例代码: :root { --size: 20 } div { font-size: var(--size)px /* 错误使用 */ } 你可能已经预料到font-size的值会产生20px,但这是错误的使用方式。浏览器会将其解释为20 px注意20px之间有一个空格 因此,如果你必须创建单个指令,则用一个CSS自定义属性来表示整个指令,比如--size:20px或者使用calc()函数,比如calc(var(--size) * 1px)(当--size设置为20时)。 如果你对这一点不怎么理解,没关系,在接下来的示例中会详细的解释这部分内容。

我们来动手做点东西

这是我们这篇文章中一直期待的一部分。将能过构建一些有用的项目来实践前面所讨论到的相关概念。还等什么呢?我们开始吧。

使用CSS自定义属性创建伟德1946手机版变量

假设我们要创建两个不同的按钮。这两个按钮的样式基本相同,只是略有一些细节不一样。 CSS自定义属性 在这个示例中,只有background-colorborder-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; } .btn:hover { cursor: pointer; background: black; color: white; } 那么,对于略有差异的按钮效果怎么来实现呢?看下面的代码: .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; } .btn:hover { cursor: pointer; background: var(--color, black); color: white; } 当你设置background:var(--color,black)时,其意思就是background的值是CSS自定义属性--color的值。当--color不存在时,就会使用其默认值black 这就是给CSS自定义属性设置默认值的方法。就像JavaScript或其他编程语言一样。这样使用是很有意义的。 对于有差异的按钮,你只需要像下面这样提供CSS自定义属性的新值就可以: .btn.red { --color: red } 这就是两个按钮所有的样式代码。现在,当你使用.red类名时,浏览器会解析出不同的颜色值,并立即更新按钮的样式效果。 如果你花大量时间构建可重用的伟德1946手机版,像这样使用CSS自定义属性就会很方便。来看看他们之间对比的截图: CSS自定义属性 如果在你的伟德1946手机版库中,还有其他风格的按钮效果,使用CSS自定义属性,你就可以省去很多额外的时间: CSS自定义属性

使用CSS自定义属性切换Web站点的皮肤

切换Web网站的皮肤效果,我想你以前肯定有碰到过。比如像下面这样的效果: 那么这样的一个效果,使用CSS自定义属性能有多简单呢?我们来一起看看。 CSS自定义属性 在此之前,我想先提一下,这个例子非常的重要。在这个示例中,将会涉及到使用JavaScript更新CSS自定义属性的一个方法。

我们真正想做的

CSS自定义属性美妙之处在于它们的响应性。一旦它们被更新,只要属性的值使用了CSS自定义属性,就将会被更新。 从概念上讲,下面这张图,能很好的解释整个过程。 CSS自定义属性 因此,需要通过JavaScript给按钮添加点击事件的监听。 对于这个简单的示例,都是基于CSS自定义属性来对整个页面的背景颜色和文本颜色做切换。也就是说,当用户点击上面的任一按钮时,他们将CSS自定义属性设置为其他颜色。因此,页面的背景颜色和文本颜色会做相应的变化,从而实现切换皮肤的效果。

模板结构

页面所需的模板结果如下: <div class="theme"> <button value="dark">dark</button> <button value="calm">calm</button> <button value="light">light</button> </div> <article> ... </article> .theme容器中包含了三个button。另外为了节约篇幅,把article元素中的内容省略了。

页面样式

这个项目的成功之处就是页面的样式。而其中的诀窍又很简单。我们没有直接设置background-colorcolor的值,而是基于CSS自定义属性来给他们设置属性值。下面就是我想要表达的意思: body { background-color: var(--bg, white); color: var(--bg-text, black) } 要实现切换皮肤的效果,原因很简单。每当单击一个按钮时,将要更改body中对应的两个CSS自定义属性的值。在更改之后,页面的整体样式将被更新。是不是非常的简单。 CSS自定义属性 接下来,我们看看怎么通过JavaScript来实现CSS自定义属性值的更新。

添加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 } } 看到上面这一坨JavaScript代码,千万别吓到你。事实上这比你想像的要简单得多。 首先,通过const root = document.documentElement来获取根元素。这里的根元素指的就是<html>元素。明白这一点是非常重要的。如果你感到好奇,这并奇怪,因为它需要设置CSS自定义属性的新值。 同样的,可以通过const themeBtns = document.querySelectorAll('.theme > button')选到.theme元素下的所有button元素。querySelectorAll会生成一个类似数组的数据结构,需要对这个数组进行循环遍历。遍历每个按钮,并给其添加一个单击事件监听器。具体方法如下: themeBtns.forEach((btn) => { btn.addEventListener('click', handleThemeUpdate) }) 接下来我们解释一下handleThemeUpdate函数。每个按钮补点击时都会有一个handleThemeUpdate作为它的回调函数。注意,什么按钮被点击,然后执行正确的操作变得非常重要。 在此基础上,使用了一个operator开关器,并根据被单击的按钮的值执行一些操作。现在你再看一下JavaScript代码,你就能很轻易的理解它了。

构建CSS自定义属性展台

接下来我们将要构建一个CSS自定义属性展台: CSS自定义属性 记住,盒子的颜色是动态更新的,并且盒子的容器在三维空间中旋转,而且是随着range输入的值做想应的角度旋转: CSS自定义属性 你可以在文章前面的示例中体验一下案例的效果。这是使用JavaScript更新CSS自定义属性的典型案例之一。 接下来,咱们一起看看这个案例是怎么实现的。

模板结构

以下是所需的伟德1946手机版:
  • 一个range的输入框
  • 存放指令的容器
  • 包含其他输入框的容器,以及每个输入框所包含的输入字段
CSS自定义属性 结构很简单: CSS自定义属性 有几个方面需要注意:
  • input type=range的值的范围是-5050,每次移动的值是5,其最小输入值为-50
  • 如果你不确定这个range输入是如何工作的,可以先查阅相关的文档
  • 请注意如何使用.color-boxes.color-box容器类名,在这些容器中存在input
  • 值得一提的是,第一个input的默认值是red
了解了文档的结构之后,就可以这样做了: CSS自定义属性
  • .slider.instructions容器设置为绝对定位,让其脱离文档流
  • body元素设置一个background-color,并且在其左下角添加一个花的背景图
  • .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的效果需要更多的代码。由于我们使用background-colorbackground-image来给body设置样式。所以使用background的简写属性来设置多个背景可能是最好的一种选择。 body { margin: 0; color: rgba(255,255,255,0.9); background: url('http://bit.ly/2FiPrRA') 0 100%/340px no-repeat, var(--primary-color); font-family: 'Shadows Into Light Two', cursive; } url指向的是向日葵图片的地址,接下来的一组属性0 100%表示背景图像的位置。接下来的内容简单的介绍了CSS背景图像定位的基本原理。 CSS自定义属性 CSS自定义属性 /后的另一部分表示background-size的值。如果你把这个值缩小,那么背景图像也会相应的缩小。no-repeat你可能知道其意思。它用来防止背景图像不重复铺满body元素。最后,逗号后面的任何东西都是用来声明第二个背景的。在我们这个示例中,第二个背景只设置了一个背景颜色,而且其值是var(--primary-color) 你一看就知道,它就是一个CSS自定义属性。这也意味着你必须先声明这个CSS自定义属性。比如: :root { --primary-color: rgba(241,196,15 ,1) } --primary-color的原值是yellow。这没什么大不了的,接下来我们很快会在那里设置更多的CSS自定义属性。现在我们要做的是将.color-boxes放到页面的正中间: main.booth { min-height: 100vh; display: flex; justify-content: center; align-items: center; } main容器是一个Flex容器,并正确地将其子元素设置到页面的正中心位置。另外再把.color-boxes和他的子元素做得更好看一点。 .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); } 设置了一个阴影效果。效果看上去有一些酷酷的感觉。咱们继续给.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; } 你知道这是什么吗?在这里有一个新的CSS自定义属性,我们应该将其添加到:root选择器中。 :root { --primary-color: rgba(241,196,15 ,1); --secondary-color: red; } 第二种颜色是red。这将给容器设置一个red背景色。 接下来的代码可能会让部分同学感到困惑: .color-boxes { transform: perspective(500px) rotateY( calc(var(--slider) * 1deg)); transition: transform 0.3s } 暂时,我们可以简化上面的transform属性的值。 CSS自定义属性 例如: transform: perspective(500px) rotateY( 30deg); transform使用了两个不同的函数。一个是perspective(),另一个是rotateY()。那么这两个函数有什么作用呢? perspective()函数应用于3D空间中被变换的函数。它将激活三维空间,并在z轴上赋予元素深度。
有关于perspective()这方面更多的资料,你可以点击这里这里进行了解。
rotateY()函数又是怎么一回事呢?通过perspective()函数激活的三维空间中,元素有xyz等平面,其中rotateY()函数会让元素沿着y平面旋转。 下图来自于codrops的图,能更好的帮助你理解这方面相关的知识。
有关于transform方面更多的介绍,可以点击这里进行了解。
我希望这些能帮助你消除一些压力。那我们回到开始的地方吧。 CSS自定义属性 当你移动滑块时,你知道什么函数会影响.container-box的旋转吗? 它会被调用的rotateY()函数,让这个盒子沿着Y轴旋转。由于传入rotateY()函数的值将是通过JavaScript来更新,因此它的值应该用一个CSS自定义属性来表示。 CSS自定义属性 那么为什么用1deg乘以这个CSS自定义属性呢? 从经验上来说,建议构建单一的指令时,将值存储在没有带单位的CSS自定义属性中。然后通过calc()函数将它们转换成任何你想要的单位。 CSS自定义属性 当你有这些值的时候,你可以用这些值做任何你想做的事情。想要转换成degvw,你都可以任意选择。 在这种情况下,通过将number值乘以1deg来把数字转换成带有单位的值。 CSS自定义属性 由于CSS是不理解数学计算的,所以你必须通过calc()函数来完成。一旦完成,我们就变得容易多了。这个变量的值可以在JavaScript中进行更新。 对于CSS来说,现在只剩下一点点了。 .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选择器来选择每个子元素。 CSS自定义属性 这里你需要有一些远见。我们知道我们将更新每个盒子的背景颜色。我们还知道,这个背景颜色必须由一个CSS自定义属性来表示,所以它可以通过JavaScript来访问。对吧。 因此,我们可以这样做: .color-box:nth-child(1) { background: var(--bg-1) } 非常容易的一件事。不过有一个问题。如果这个变量不存在,又会发生什么呢?根据前面介绍的内容,针对这一问题,我们需要做一个降级处理。就是添加一个默认颜色,比如像下面这样: .color-box:nth-child(1) { background: var(--bg-1, red) } 在这个特殊的案例中,我选择不提供任何的降级处理。 如果在属性值中使用CSS自定义属性无效,则该属性将接受其初始值。这一点前面已经提到过了。因此,当--bg-1无效或不可用时,background将默认为其初始值transparent. 初始值是指当属性没有显式设置时的值。例如,如果不设置元素的背景颜色,它将默认为transparent。初始值是一种默认的属性值。

加入一些JavaScript代码

对于JavaScript代码,我们要做的事情会很少。 首先让我们来处理滑块。仅只需要五行代码就可以了。 const root = document.documentElement const range = document.querySelector('.booth-slider') range.addEventListener('input', handleSlider) function handleSlider (e) { let value = e.target.value root.style.setProperty('--slider', value) } 这对你而言是不是很简单,对吧。 首先,通过const range = document.querySelector('.booth-slider')选到了滑块元素。然后使用range.addEventListener('input', handleSlider)input元素添加一个监听事件,当input的范围值得到改变时,将会调用handleSlider回调函数。 接下来做的就是编写handleSlider回调函数: function handleSlider (e) { let value = e.target.value root.style.setProperty('--slider', value) } CSS自定义属性 root.style.setProperty('--slider', value)的意思是获取根元素的style样式,然后设置其属性值。

处理颜色变化

就像处理滑块值的变化一样简单。 const inputs = document.querySelectorAll('.color-box > input') 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')获取所有input元素。然后给所有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自定义属性 唷,唷,唷.......就是这么的简单。全部搞定!

还错过了什么

当我注意到我在任何地方都没有提到浏览器对CSS自定义属性的支持时,我已经完成了这篇文章的初稿。现在也该来收拾一下相应的残局了。 浏览器对CSS自定义属性的支持并不坏。可以说相当的不错,到目前为止所有的现代浏览器中都对CSS自定义属性做了良好的支持。在写这篇文章的时候,已经超过87%了。 CSS自定义属性 那么问题来了,我现在可以在项目中使用CSS自定义属性了?我的回答是的!不过,一定要检查一下你自己的用户群体。 值得庆幸的是,你可以使用Myth这样的处理器。它将把一些CSS未来的特性做了相应的处理。言外之意,还未支持的CSS特性,你现在就可以使用,听起来是不是很爽。难道不是吗? 如果你有使用PostCSS的经验,那么这同样是使用未来CSS的一个很好的方法。这里有一个CSS自定义属性的PostCSS模块
如果你从未接触过PostCSS相关的东西,那么你有必要花点时间去了解或者学习一下了
那今天就到这里吧。这就是我要和大家聊的东西,有关于CSS自定义属性,应该掌握的一些知识点。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等伟德19463331脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。
如需转载,烦请注明出处:https://www.w3cplus.com/css/everything-you-need-to-know-about-css-variables.html
返回顶部