3

介绍一种CSS变量未定义语法也OK的小妙招

 2 years ago
source link: https://www.zhangxinxu.com/wordpress/2022/06/css-var-optional-empty-trick/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

介绍一种CSS变量未定义语法也OK的小妙招

这篇文章发布于 2022年06月12日,星期日,01:07,归类于 CSS相关。 阅读 777 次, 今日 139 次 3 条评论

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10440 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

占位图 CSS变量技巧

一、先看案例

在《CSS世界》P30 页那里有介绍过一个 transform 动画和 transform 定位冲突的场景,如下图所示:

冲突描述场景

用一句话描述就是:

弹框等居中定位元素如果使用 transform:translate(-50%,50%) 偏移实现,则定位元素的显示动画如果包含 transform 变化,则会发生冲突,使定位失效。

我书中提出的解决方案是宽高设置为 fit-content,这样就可以使用 inset:0 + margin:auto 实现不影响 transform 动画的居中对齐效果了。

除了使用兼容性好不太好的 translate,scale,rotate属性进行分离设置外,最近我发现,其实还有一种更另类的巧妙方法可以处理此问题。

那就是逗号后面留空的 CSS 自定义属性语法,例如:

transform: var(--transform, ) scale(1);

二、深入CSS变量缺省值

CSS变量浏览器还没有怎么支持的时候(2016年)我就率先研究与介绍过了,见此文“了解CSS变量var”,里面介绍了很多CSS变量的细节知识。

然而,学无止境,我以为了解了全部,实际上还是有知识的盲区。

下面这个基础特性相信大家都知道。

即 CSS 变量是支持缺省值的,也就是当 CSS 自定义属性没有定义的时候使用的值,例如下面的用法示意:

color: var(--color, skyblue);

如果 --color 未定义,我们就使用 skyblue 作为颜色值。

但是,怕是很多人并不知道,后面的那个默认兜底的缺省值是可以不写的,注意,是不写,不是没有这个参数,参数还在,表现出来的效果就是括号内有个光秃秃的逗号,就像下面这样:

color: var(--color, );

这是什么意思呢?

就是如果 --color 未定义,则此变量当作没存在,未设置。

注意,这个语法和下面的语法区别巨大,不是同一个东西。

color: var(--color);

我们看一个例子就知道区别在哪里了,有如下的 HTML 和 CSS:

<p class="zhang">颜色是?</p>
<p class="xinxu">颜色是?</p>
.zhang {
  color: deeppink var(--color, );
}
.xinxu {
  color: deeppink var(--color);
}

此时,.zhang 类名对应的 <p> 元素的颜色和 .xinxu 类名对应的 <p> 元素是不一样的,实际渲染效果如下截图所示(实时渲染,桌面浏览器可以打开控制台查看源码):

可以看到,上面一行文字的颜色是深粉色,而下面一行的文字颜色是黑色。

原因在于当 --color 未定义的时候,deeppink var(--color, ) 等同于 deeppink,因此颜色是深粉色,而 deeppink var(--color) 可以看成是 deeppink undefined ,语法无效,于是使用继承的黑色。

三、在多值CSS属性中的应用

对于单值 CSS 属性,空白缺省值的价值并不是很明显,因为使用或者不使用区别并不是很大。

div {
    border-radius: var(--radius, );
}
div {
    border-radius: var(--radius);
}

的渲染表现都是一致的。

但是在多值 CSS 属性中,情况就完全不同了。

回到一开始的 transform 冲突的场景这里,如果我们的 transform 动画这么设置,那么就能很大程度上避免 transform 属性使用冲突的问题了。

@keyframes scaleIn {
    from {
        transform: var(--transform, ) scale(0.1);
    }
    to {
        transform: var(--transform, ) scale(1);
    }
}

此时,如果元素需要使用 transform 定位也是可以的了:

.target {
    position: fixed;
    left: 50%; top: 50%;
    --transform: translate(-50%, -50%);
}

此时,动画执行的时候,会把 --transform 的属性值自动插入进去。

如果元素没有设置 --transform 变量,也没有关系,动画会单纯按照 scale(.1) -> scale(1) 进行动画,功能完全不受影响。

关于这个例子,我专门做了在线demo,您可以狠狠地点击这里:transform多CSS属性值依然动画效果demo

效果录屏示意:

scale动画不冲突示意

几个多值CSS属性示意

CSS多值属性还是很多的,一种是缩写属性(使用空格和斜杠分隔),还有一种是可无限值属性(使用逗号分隔)。

除了 transform 属性外,常见的还有:

filter: invert(1) hue-rotate(.5turn) var(--filter,);
background: linear-gradient(deeppink, deepskyblue) var(--bgcolor,);
box-shadow: 2px 2px 4px #0003 var(--box-shadow,);

以及 grid, border-image, columns, offsets, text-decoration 等非常多的属性,就不一一举例了。

对了,对于逗号分隔的多数组值,在定义CSS变量的时候,前面记得把逗号写上。

--box-shadow: ,0 0 5px #0002;

四、结语说明

一句话,CSS变量赛高之神。

目前在移动端项目中大家可以放心使用,其实我看很多 PC 网站都在使用了,比方说 Bilibili,这玩意真的好事,很多特性都很强,例如各种类型的 CSS 属性值都能支持,容错性也强到离谱,远不是大家认为的换换颜色这么简单。

好了,就说这么多,感谢大家的阅读!

如果您觉得本文内容还不错,欢迎。

2764.svg

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=10440


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK