在 CSS 中,一些属性有简写形式。一个属性可以接受分隔的值。正如人们所说,语法糖 使编写更容易。例如 transition
,可能看起来像这样
.element {
transition: border 0.2s ease-in-out;
}
我们可以这样写
.element {
transition-property: border;
transition-duration: 0.2s;
transition-timing-function: ease-in-out;
}
简写值的每个“部分”都有它自己的映射属性。但并非所有情况都如此。以 box-shadow
为例
.element {
box-shadow: 0 0 10px #333;
}
这不是其他属性的简写。没有 box-shadow-color
或 box-shadow-offset
。
这就是自定义属性来拯救我们!
我们可以像这样设置它
:root {
--box-shadow-offset-x: 10px;
--box-shadow-offset-y: 2px;
--box-shadow-blur: 5px;
--box-shadow-spread: 0;
--box-shadow-color: #333;
}
.element {
box-shadow:
var(--box-shadow-offset-x)
var(--box-shadow-offset-y)
var(--box-shadow-blur)
var(--box-shadow-spread)
var(--box-shadow-color);
}
可能有点冗长,但可以完成工作。
现在我们已经做到了,请记住我们得到了一些独特酷炫的东西
- 我们可以用 JavaScript 更改单个值。例如
document.documentElement.style.setProperty("--box-shadow-color", "green");
- 如果需要,可以使用层叠。如果我们在比 :root 更具体的任何选择器上设置
--box-shadow-color: blue
,我们将覆盖该颜色。
回退也是可能的,以防变量根本没有设置
.element {
box-shadow:
var(--box-shadow-offset-x, 0)
var(--box-shadow-offset-y, 0)
var(--box-shadow-blur, 5px)
var(--box-shadow-spread, 0)
var(--box-shadow-color, black);
}
变换怎么样?它们很有趣,因为它们采用以空格分隔的值列表,因此它们中的每一个都可以是自定义属性
:root {
--transform_1: scale(2);
--transform_2: rotate(10deg);
}
.element{
transform: var(--transform_1) var(--transform_2);
}
对于确实具有简写形式的单个属性,但也提供以逗号分隔的多个值的元素怎么办?另一个很棒的用例
:root {
--bgImage: url(basic_map.svg);
--image_1_position: 50px 20px;
--image_2_position: bottom right;
}
.element {
background:
var(--bgImage) no-repeat var(--image_1_position),
var(--bgImage) no-repeat var(--image_2_position);
}
或者过渡?
:root {
--transition_1_property: border;
--transition_1_duration: 0.2s;
--transition_1_timing_function: ease;
--transition_2_property: background;
--transition_2_duration: 1s;
--transition_2_timing_function: ease-in-out;
}
.element {
transition:
var(--transition_1_property)
var(--transition_1_duration)
var(--transition_1_timing_function),
var(--transition_2_property)
var(--transition_2_duration)
var(--transition_2_timing_function),
}
Dan Wilson 最近 使用这种方法 与动画一起展示了如何暂停单个动画!
以下是浏览器支持情况
此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器从该版本开始支持该功能。
台式机
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
49 | 31 | 不支持 | 16 | 10 |
移动设备/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 10.0-10.2 |
我不确定是否要将
box-shadow
之类的每个值都单独定义。我一直在使用的做法类似于--boxshadow_lg: 0 8px 6px -6px rgba(0,0,0,.15);
--boxshadow_sm: 0 2px 3px -3px rgba(0,0,0,.15);
然后我就可以通过
box-shadow: var(--boxshadow_lg);
调用它们,就完成了。当然,我可以将某些元素更改为变量以进一步减少冗余,但这似乎是一种相当有效的方式来实现“易于更新”和“易于调用”的组合也许不应该!
但是,这正是重点。您实际上**不能**设置
box-shadow-color**,但是使用 CSS 自定义属性,您就可以做到。
Caniuse 表示 Android 版 FireFox 确实支持。当然,iPhone 版 Firefox 使用 WebKit,因此如果 Mobil Safari 支持,FF 应该在那里也支持。
太棒了!
嗨,Chris,是否可以(或者您对此有什么想法)从 HTML 属性的调用中调用变量?类似这样
root: {
--align-left: left;
--align-center: center;
--align-right: right;
}
p {
text-align: var('--align-' attr(data-align));
}
不行。这也是一个坏主意,因为您会混合内容和表示形式。这就是
align
属性已弃用的原因。您可以使用
attr()
和变量做几件事,如目前浏览器所支持的那样(其中attr()
始终返回字符串)。理论上,如果您支持完整的 CSS 3
attr()
函数 (允许您告诉浏览器将属性值解析为颜色、长度、url 或其他数据类型),您可以做更多的事情。然而,它们都不像您的代码。您不能动态地组合变量名称。
var()
只能更改值。现在您可以做的是在元素的
style
属性中设置变量,并使用它们从样式表中触发坐标样式更改。写得很棒!我认为 Dan Wilson 在他的文章 这里 比你先一步
哦,我刚注意到你已经链接到那里了
我过去是如何处理动态 CSS 的
我在
<head>
中使用<style class="dynamic-css">
,并通过在 JavaScript 中连接字符串来动态创建其内容。我也可以有“回退”,我只是将它们写入我的常规样式表中。这甚至更兼容浏览器,因为它依赖于使用了很长时间的技术。我承认
setProperty()
是一种设置 CSS 属性的便捷方法,但代价是仍然缺乏浏览器支持,尤其是在移动设备上。那么……我如何再次使用它与 scss?
因此,自定义属性不过是定义变量然后在 CSS 文件中的其他位置使用这些变量的能力。
不错,Chris!