currentColor与CSS自定义属性之间的差异
变量对于CSS而言是这两年大家关注的一个话题。对于变量而言,最早是出于CSS的一些处理器语言当中,比如Sass、LESS之类的。随着CSS的发展,变量的概念也被引入到CSS中。时至今日,在CSS中的变量不被称作变量,而被称为CSS自定义属性。该特性让我们维护CSS、编写CSS变得更易。而事实上呢?在CSS最早的变量之一是currentColor
。该特性也可以更好的帮助我们编写CSS和扩展CSS。那么今天我们来开另一个话题,currentColor
和CSS自定义属性又有何差异呢?接下来的内容,我们就来一起探讨这方面的细节。
currentColor
和自定义属性之间还是存在一些有趣的区别。这两个都是CSS中动态属性的例子,但是它们的解析方式在一些非常重要的方面还是有所不同的。至于为何不同,接下来的内容将向大家揭开。
currentColor
简单的回忆一下CSS中的变量关键词currentColor
。这个关键词就像是一个CSS变量,不同的是它有一个主要的限制:
只可以在接受
<color>
值的地方使用它;如果该属性不能接受<color>
值,它就不能接受currentColor
作为值。
在CSS中,能接受<color>
值的属性比较多,比如border-color
、background-color
、box-shadow
、text-shadow
、outline
以及CSS渐变属性等。如果我们希望元素的边框、阴影、背景等颜色和color
同步,那么我们就可以使用currentColor
。比如:
box-shadow: inset 2px 2px 3px currentColor;
background-color: currentColor;
border-color: currentColor;
background-image: linear-gradient(to bottom, currentColor, rgba(0,0,0,0));
当然,currentColor
和其它变量之间的另一个区别是,你没办法用给其它变量赋值的方法给它赋值。currentColor
的值是由当前元素使用的color
属性的计算值决定的。比如下图所录制的效果:
正如上图所示,在currentColor
变量的帮助下,改为color
属性的值,所有继承了color
的UI组件的颜色也会随着改变。
有关于
currentColor
更详细的介绍,可以阅读早前整理的《使用CSS的currentColor
变量扩展颜色级联》一文。
CSS自定义属性
了解了currentColor
之后,再来简单的回忆一下CSS中的自定义属性。CSS自定义属性最早的思路来源于CSS处理器中的变量,其最早也常被称为CSS的变量,但事实上他和变量还是有很大的差异的,所以后面为了更为统一化,将这一特性称之为CSS自定义属性。更为值得庆幸的是,该特性被纳入到了W3C规范中,成为一个独立的模块,即:CSS Custom Properties for Cascading Variables Module Level 1。
CSS自定义的属性使用其实非常的简单,他也类似于CSS其他处理器一样,需要先声明,然后在调用。声明CSS自定义属性非常的简单,使用--
为前缀,带一变量名和变量值,这样就声明了一个自定义属性,比如:
:root {
--color: red;
}
在根元素:root
中声明了一个--color
自定义属性,该属性被称为全局性的,当然我们也可以在某个CSS规则块中声明:
.box {
--color: blue;
}
同样是声明了一个--color
属性,只不过这个是属于局部的。声明之后,我们在调用的时候,可以使用var()
函数来调用,比如:
.box {
color: var(--color);
}
CSS自定义属性,使用就是这么的简单。但自定义属性中还有很多很有意思的东西。只不过不在这里进行阐述,如果感兴趣的话,可以阅读小站上有关于CSS自定义属性相关的文章。
currentColor和CSS自定义属性之间的差异
通过前面的内容,我们简单的了解了CSS中currentColor
和CSS自定义属性在CSS中所起的作用。接下来我们回到今天真正的主题上来。这两者之间有何差异。
假设我们有一个这样的场景,我们希望标题的边框和正文的颜色应用同一种颜色。如下图所示:
事实上实现上面的效果并不是难事。难得是我们如何以最少的代码量和最简易方式来实现。特别是面对换肤的需求时,我们如何可以最简易地做到这一点。比如说,通过一个类来理想的设置皮肤效果。
假设我们希望改变的body
的文本颜色 而不仅仅是段落的颜色,因此在容器元素上设置color
。刚开始这样设置是有意义的,因为这样做允许容器内的所有元素都会继承主题的颜色,然后我们可以将标题的颜色重置为black
。
但我们有一个前提性的需求,只想在一个地方设置颜色,而标题上的border-color
要继承这个颜色,目的是希望标题边框的颜色和主体文本颜色一样。或许你会想到CSS中的继承关键词inherit
。但事实上呢?像下面这样设置,并未达到我们的需求:
body {
color: red;
}
h3 {
color: #000;
border-color: inherit;
}
边框的颜色也变成了#000
,如下图所示:
注意,虽然在border-color
属性中显式的设置了值为inherit
关键词,其实得到的效果和在border
属性中不显式设置border-color
得到的效果是一样的:
border: 3px double;
这是因为,在border
属性中,如果未显式的设置border-color
的值时,边框的颜色会继承文本color
的值。
为什么会这样呢?我们来简单的说一下其中的原理。
由于body
中(或者你为一个主题设置了一个全局的类,比如theme
这样的类)只设置了color
的值为red
,并未显式设置border-color
的值。这也造成border-color
的值使用的是默认值,而border-color
的默认值是currentColor
。也就是说,基于此例的上下文,currentColor
的值是red
,这也是预期想要继承的值。
既然如此,为什么效果和我们所预期的不一样呢?这之间倒底是发生了什么呢?这主要是因为我们在h3
标题中重置了color
的值为#000
,而border-color
仍然从父元素继承值,但结果是,当我们继承currentColor
时,并未从父元素中检索该属性的解析值,相反,我们inherit
关键词本身,计算值将在本地上下文中解析。所以造成上面示例中的border-color
为#000
。简单的来看一下这样的过程:
- 在
body
元素中,border-color
采用的是默认值currentColor
,即red
(在本例中) - 在
h3
中,显式的设置了border-color
值为关键词inherit
,即继承了父元素border-color
的值,也就是继承了currentColor
的值
根据前面currentColor
的内容可得知,他的值取决于元素自身的color
值,而上例中,为了重置标题的文本颜色为black
,所以显式的重置了该元素的color
值为black
,这样也就直接影响了currentColor
的值,因此最终大家看到的效果就是标题的边框颜色也变成了黑色。
有关于
inherit
更为深入的介绍,建议阅读前面整理的《图解CSS:CSS层叠和继承》和《管理CSS层叠》。
上面也提到了,h3
显式设置了border-color
的值为inherit
,继承了border-color
的值currentColor
,而currentColor
取决于自身元素的color
值。如此一来,要解决这个问题就显得非常的简单了,我们只需要在body
元素上显式的设置border-color
为red
即可:
body {
color: red;
border-color: red;
}
h3 {
color: black;
border-color: inherit
}
现在h3
的border-color
不再继承动态属性currentColor
,其颜色按预期的继承了red
。得到了我们想要的效果:
我们达到了预期的目标,只需要在body
上设置颜色即可。如果我们现在更换主题颜色,那么只需要在body
上重置即可,如下图所示:
其实这已经是我们想要的了,但事实上,我们还有更为简易的方式来帮助我们维护。那就是借助CSS自定义属性。尽管CSS自定义属性也是动态的,但在相同情况之下,CSS自定义属性不会像currentColor
那样工作。比如说,我们使用CSS自定义属性来修改上面的示例:
body {
--color: red;
color: var(--color);
border-color: var(--color);
}
h3 {
--color: black;
color: var(--color);
border-color: inherit;
}
在这种情况之下,h3
的border-color
继承了父元素body
的自定义属性--color
。但是,即使h3
的color
的值是本地的自定义属性--color
(局部变量),它的border-color
也不会像currentColor
那样使用这个本地声明的自定义属性值。
继承自定义属性设置的值始终与父属性解析的值相匹配。
注意,本例中的
color
属性将取局部的值,因为它不是继承的。
这里的关键区别是:currentColor
关键词不是在计算值时解析,而是对本地color
属性的使用值的引用。
总结
一开始,我一直以为currentColor
关键词和CSS自定义属性非常的相似,都是相似的动态属性。然而事实证明,有一些根本的区别是我们应该要意识到的。比如文章中所举例的示例,再次强调了CSS自定义属性和currentColor
之间是有所不同的。air max 90 essential release