使用 translate
、rotate
和 scale
属性变换元素
CSS transform
属性
要将变换应用于元素,请使用 CSS transform
属性。该属性接受一个或多个 <transform-function>
,它们会依次应用。
.target {
transform: translateX(50%) rotate(30deg) scale(1.2);
}
目标元素在 X 轴上平移 50%,旋转 30 度,最后缩放到 120%。
虽然 transform
属性可以很好地完成其工作,但当您想要单独更改其中任何一个值时,它会变得有点乏味。
要在悬停时更改比例,您必须复制 transform 属性中的所有函数,即使它们的值保持不变。
.target:hover {
transform: translateX(50%) rotate(30deg) scale(2); /* Only the value of scale() changed */
}
单独的变换属性
Chrome 104 中引入了 CSS 变换的单独属性。这些属性是 scale
、rotate
和 translate
,您可以使用它们来单独定义变换的这些部分。
通过这样做,Chrome 加入了已经支持这些属性的 Firefox 和 Safari。
使用单独属性重写前面的 transform
示例,您的代码段将变为这样
.target {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
顺序很重要
原始 CSS transform
属性与新属性之间的一个关键区别是声明的变换的应用顺序。
对于 transform
,变换函数按照它们编写的顺序应用 – 从左(外部)到右(内部)。
对于单独的变换属性,顺序不是它们声明的顺序。顺序始终相同:先 translate
(外部),然后 rotate
,最后 scale
(内部)。
这意味着以下两个代码段都给出相同的结果
.transform--individual {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
.transform--individual-alt {
rotate: 30deg;
translate: 50% 0;
scale: 1.2;
}
在这两种情况下,目标元素都将首先在 X 轴上平移 50%
,然后旋转 30deg
,最后缩放 1.2
。
如果单独的变换属性之一与 transform
属性一起声明,则单独的变换首先应用(translate
、rotate
,然后是 scale
),而 transform
最后应用(内部)。有关更多详细信息,请参阅定义 如何计算变换矩阵 的规范。
动画
添加这些属性的主要原因是为了使动画更轻松。假设您想要按如下方式为元素设置动画
使用 transform
要使用 transform
实现此动画,您必须计算所有已定义变换的所有中间值,并将这些值包含在每个关键帧中。例如,要在 10% 标记处进行旋转,还必须计算其他变换的值,因为 transform
属性需要所有这些值。
生成的 CSS 代码变为这样
@keyframes anim {
0% { transform: translateX(0%); }
5% { transform: translateX(5%) rotate(90deg) scale(1.2); }
10% { transform: translateX(10%) rotate(180deg) scale(1.2); }
90% { transform: translateX(90%) rotate(180deg) scale(1.2); }
95% { transform: translateX(95%) rotate(270deg) scale(1.2); }
100% { transform: translateX(100%) rotate(360deg); }
}
.target {
animation: anim 2s;
animation-fill-mode: forwards;
}
使用单独的变换属性
使用单独的变换属性,这变得更容易编写。您无需将所有变换从一个关键帧拖动到另一个关键帧,而是可以单独定位每个变换。您也不再需要计算所有这些中间值。
@keyframes anim {
0% { translate: 0% 0; }
100% { translate: 100% 0; }
0%, 100% { scale: 1; }
5%, 95% { scale: 1.2; }
0% { rotate: 0deg; }
10%, 90% { rotate: 180deg; }
100% { rotate: 360deg; }
}
.target {
animation: anim 2s;
animation-fill-mode: forwards;
}
使用单独的变换属性和多个关键帧
为了使您的代码模块化,您可以将每个子动画拆分为其自己的一组关键帧。
@keyframes move {
0% { translate: 0% 0; }
100% { translate: 100% 0; }
}
@keyframes scale {
0%, 100% { scale: 1; }
5%, 95% { scale: 1.2; }
}
@keyframes rotate {
0% { rotate: 0deg; }
10%, 90% { rotate: 180deg; }
100% { rotate: 360deg; }
}
.target {
animation: move 2s, scale 2s, rotate 2s;
animation-fill-mode: forwards;
}
由于这种拆分,您可以根据需要应用每个单独的关键帧集,因为 transform
属性(现在已成为单独的属性)不再相互覆盖。最重要的是,您可以为每个变换赋予不同的时序,而无需重写全部内容。
性能
使用这些新属性的动画与现有 transform
属性的动画一样高效。
translate
、rotate
和 scale
的动画在合成器上以与 transform
动画相同的方式运行,因此它们在 与 transform
相同的方式 中有利于动画性能。
这些新属性也适用于 will-change
属性。通常,最好避免过度使用 will-change
,方法是在所需的最少数量的元素上使用它,并在尽可能短的时间内使用它。但尽可能具体也是有益的。例如,如果您使用 will-change
来优化具有 rotate
和 filter
属性的动画,则应使用 will-change: rotate, filter
声明此内容。在您为 rotate
和 filter
设置动画的情况下,这比使用 will-change: transform, filter
稍好,因为当您使用 will-change
时,Chrome 预先创建的一些数据结构对于 transform
与 rotate
是不同的。
“新近可互操作系列”的一部分