「这是我参与2022首次更文挑战的第39天,活动详情查看:2022首次更文挑战」
前提
假设,你有一个类元素,拥有多个css属性值,如下所示:
.el {
transform: translate(100px) scale(1.5) skew(5deg);
}
有时,你并不想使用所有的transform值,你希望有些属性值是可选的,此时你可能会想到var
var
使用var定义可选属性值
.el {
/* |---- 默认 ----| |--- 可选 ---| */
transform: translate(100px) var(--transform);
}
可是,var似乎有时并没有达到我们预期效果,如果--transform没有定义,那么整个属性将会无效。
如何解决上面的问题呢,我使用了一个小技巧来修复它,代码如下所示:
.el {
transform: translate(100px) var(--transform, );
}
大家注意到上面代码的差别了吗:这里定义了一个fallback函数,而它的功能是将其设置成空值:(, )
这是一个又棒又非常有用的技巧哦!下面是 the specification提到关于它的内容:
In an exception to the usual comma elision rules, which require commas to be omitted when they’re not separating values, a bare comma, with nothing following it, must be treated as valid in var(), indicating an empty fallback value.
这一点与 The CSS Custom Property Toggle Trick不谋而合
示例
创建了三个div,class名称分别为defined、undefined以及no-fallback,目前只有defined内部定义了--transform、--text-shadow、--bg-color以及--filter变量值
代码如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
body{
display: grid;
place-items: center;
grid-auto-flow: column;
height: 100vh;
font: bold 20px Arial;
}
div {
cursor: pointer;
user-select: none;
padding: .5em;
display: inline-block;
}
.defined {
--transform: rotate(30deg) scale(1.5);
--text-shadow: ,0 0 5px black; /*特例:前面需要逗号*/
--bg-color: gold;
--filter: sepia(60%);
/* 多个变量定义:由默认值和可选自定义值组成 */
transform: skew(5deg) var(--transform, );
text-shadow: 0 -1px 3px white var(--text-shadow, );
background: linear-gradient(90deg, cyan, transparent) var(--bg-color, );
filter: contrast(70%) invert(10%) var(--filter, );
}
.undefined {
transform: skew(5deg) var(--transform, );
text-shadow: 0 -1px 3px white var(--text-shadow, );
background: linear-gradient(90deg, cyan, transparent) var(--bg-color, );
filter: contrast(70%) invert(10%) var(--filter, );
}
.no-fallback {
/* multi-values properties with default values + optional extra ones */
transform: skew(5deg) var(--transform);
text-shadow: 0 -1px 3px white var(--text-shadow);
background: linear-gradient(90deg, cyan, transparent) var(--bg-color);
filter: contrast(70%) invert(10%) var(--filter);
}
</style>
<body>
<div class='defined'>Defined</div>
<div class='undefined'>Undefined</div>
<div class='no-fallback'>Without Fallback</div>
</body>
</html>
运行效果如下所示:
-
.defined内部定义了各个变量值,故所有的样式皆生效,且在var内使用了(,),表示即使各个变量未定义,前面的默认样式仍然会产生效果,其效果与undefined呈现一致,感兴趣的同学可以试试 -
undefined内部没有定义上述变量值,但它使用了(,)表示若变量未定义,则返回空值,故在var前面定义的skew(5deg)等皆产生了效果 -
no-fallback内部既没有定义变量值,也未使用(,)接收空值,直接导致整条css语法无效
其他知识点:
一些属性可设置多个值,如text-shadow,它们希望得到特殊对待,即在自定义属性前面必须加上逗号,如下代码所示:
--text-shadow: ,0 0 5px black;
注意Sass编译器
当发现该技巧后,我发现Sass编译器存在一个bug:它会去掉空回调函数(,),我已经在github上反馈其问题,希望它能尽快得到解决
临时解决方案
回调函数(,)不作任何渲染,如下所示:
transform: translate(100px) var(--transform, scale(1));