transform 支持单独赋值改变

在掘金看到一篇文章

看完以后有感而发transform在制作动画时经常被占用,因为一个元素只能使用一个 transform,所以当我有多属性值需要设置时,我通常的做法是通过添加一个父元素来给它设置 transform 属性。

比如在魔改博客的过程中希望改变transform中的某一部分, 我必须把前面的部分也照抄一遍才能达到覆盖修改的目的

1
2
3
4
5
6
7
header.nav {
transform: scale(1.5); /*这样不行,会丢失translate*/
}
/*必须写完整*/
header.nav {
transform: translate(-50%, -50%) scale(1.5);
}

所以transform很需要能够像background那样能够有单独书写的属性以覆盖 transform 中的值。

但是从Chrome 104开始,浏览器终于正式支持单独赋值了

比如说

1
2
3
header.nav {
transform: translate(-50%, -50%) scale(1.5);
}

可以写成

1
2
3
4
header.nav {
translate: -50% -50%;
scale: 1.5;
}

这样如果需要改变某一部分,就只需要像普通属性一样覆盖就行了

1
2
3
header.nav {
scale: 2;
}

想了解更多的话可以去看看原文,但是这个写法实在是太新了,不建议这么玩。

基于此我们可以发散思维想一想还有什么办法可以解决transform占用的问题,没错就是 css 变量

1
2
3
div {
transform: translate(-50%, -50%) scale(1.5);
}

通过 CSS 变量,将 transform 拆分

1
2
3
4
5
div {
--translate: -50%, -50%;
--scale: 1.5;
transform: translate(var(--translate)) scale(var(--scale));
}

经过这样拆分以后,CSS 变量就成了独立属性,如果需要覆盖,只需要修改其中一个就行了,而无需关注–translate 是什么样的,这样变化的部分就可以单独作为一个公共的样式了,如下

1
2
3
4
5
6
7
8
9
.div1 {
--translate: -50%, -50%;
}
.div1 {
--translate: 10px, 10px;
}
div.scale {
--scale: 2; /*无需关注其他transform,可以作为公共的样式*/
}

这么做如果是单纯的状态变化是没有问题的,只需要使用transition: .3s;就可以实现过渡动画,不过当在做 animation 的时候,
会发现过渡不了,此时需要下面的代码来实现过渡@property属性可以让我们的自定义属性--scale的变化像 transition: .3s 那样来实现过渡效果。

1
2
3
4
5
@property --scale {
syntax: "<number>";
inherits: false;
initial-value: 1;
}