解放生产力!Transform 支持单独赋值改变

开发 前端
本文比较简单,没有复杂的 CSS 动效,主要介绍了从 Chrome 104 开始,Transform 支持单独赋值这一更新。

在 Chrome 104 中,支持了一个非常有意思的新特性。CSS 中的 ​​transform​​ 支持单独赋值改变。不要小看这一点,此点改动在很多时候,能够非常有效的解放生产力,算是一个非常 NICE 的更新。

浅析一下

什么意思呢?我们来看这样一个例子:

在之前,我们可以利用 transform 配合绝对定位的 top、left 进行任意元素的水平垂直居中,像是这样:

<div></div>
div {
width: 200px;
height: 200px;
background: #000;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

这样,我们就得到了一个水平垂直居中的元素:

图片

但是,如果我们想对这个元素进行一个缩放的动画,该怎么做呢?会是这样:

div {
width: 200px;
height: 200px;
background: #000;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
@keyframes scale {
0% {
transform: translate(-50%, -50%) scale(1);
}
100% {
transform: translate(-50%, -50%) scale(1.2);
}
}

好的,动画本身,并不是重点。重点在于,在上述的 @keyframes 代码中,我们想改变的其实只有 scale()​ 的值,但是基于现有的 CSS 机制,我们必须把前面控制定位的 ​translate()​ 一并写上。

transform 拆开书写

为了解决这个痛点,规范支持了将 transform 分开书写的方式。

所以,对于这一句,transform: translate(-50%, -50%) scale(1),我们可以分别拆开成 translate 和 scale:

div {
width: 200px;
height: 200px;
background: #000;
position: absolute;
top: 50%;
left: 50%;
// transform: translate(-50%, -50%); 删掉这句
translate: -50% -50%;
scale: 1;
animation: scale 1s infinite linear alternate;
}
@keyframes scale {
0% {
scale: 1;
}
100% {
scale: 1.2
}
}

是的,我们可以通过 translate​ 和 scale​ 分开控制它们,这样我们就能愉快的在 @keyframes​ 中,只进行 scale 的动画了!妙哉。

所以,根据规范 -- [1],于 transform 而言,我们可以将它整个拆解为:

  1. translate
  2. rotate
  3. scale

具体的语法会有一点点不同,具体使用的时候,多看看文档,譬如 translate 接收 3 个参数,第 2、3 个参数如果不存在,则为零(例如:translate: 50% 50% 0)。又譬如 rotate,如果想改变 Y 轴的旋转角度,可以这样写 rotate: y 30deg。

再举个例子,下面两组代码是等效的:

// 上下两组代码产生的效果等效!
{
transform: translate(-50%, -50%) rotateZ(30deg) scale(1.2);
}
{
translate: -50% -50%;
rotate: Z 30deg;
scale: 1.2;
}

是的,比较奇怪的是,规范里没有涉及到 skew 的拆解。

顺序对 transform 的影响

当然。拆开后和原本写在一起并非完全一样。

如果,我们使用的是 transform,将它们全部写在一起,像是这样:

div {
transform: rotateY(90deg) translateZ(400px) scale(1.2);
}

此时,元素的 transform 变换遵循的是从左向右进行变换。也就是先旋转 ​​rotate​​​,再 ​​translateZ()​​​,最后缩放 ​​scale()​​。

但是如果,我们分开来写:

div {
rotate: Y 90deg;
translate: 0 0 400px;
scale: 1.2;
}

虽然代码属性的顺序是 rotate --> translate --> scale,但是实际上,无论他们的书写顺序如何,解析的时候都会按照首先 translate,然后 rotate,最后 scale 的顺序进行!

这个会有什么影响吗?当然,这里我们来看这样一个例子。假设,我们想实现这样一个立方体:

图片

不算上下两个面,以其余 4 个面为例子,正常的做法是,在 transform-style: preserve-3d 状态下,每个面先绕 Y 轴旋转一定的角度,然后进行 translateZ() 的位移。

像是这样:

图片

所以,代码会是这样:

face1 {
transform: rotateY(0) translateZ(200px);
}
face2 {
transform: rotateY(90deg) translateZ(200px);
}
face3 {
transform: rotateY(180deg) translateZ(200px);
}
face4 {
transform: rotateY(270deg) translateZ(200px);
}

注意,这里 transform 的变换是先旋转,再位移。

如果我们拆开写,变成:

face2 {
rotate: Y 90deg;
translate: 0 0 200px;
}
//...

则整个效果就变成了:

图片

因为这里实际执行的顺序是,先 translate,后 rotate。

所以,实际使用的时候一定要注意,矩阵变换的顺序会影响最终的效果。如果对顺序有严格的要求,还是需要合在一起写。

总结一下

本文比较简单,没有复杂的 CSS 动效,主要介绍了从 Chrome 104 开始,transform 支持单独赋值这一更新。其中有三点需要注意:

  1. 于transform 而言,我们可以将它整个拆解为 translate、rotate、scale 的分开写法。
  2. 对于完整的transform 而言,其执行顺序遵循从左向右进行变换。
  3. 对于分开写的transform 而言,无论其书写顺序,总是按照先 translate,然后 rotate,最后 scale 的顺序进行!

最后

好了,本文到此结束,希望本文对你有所帮助 :)

参考资料

[1]W3 - individual-transforms: ​https://www.w3.org/TR/css-transforms-2/#individual-transforms​。

[2]CodePen Demo -- 3D Box View: https://codepen.io/Chokcoco/pen/vYjpWBW?editors=0100​。

[3]Github -- iCSS: https://github.com/chokcoco/iCSS​。

责任编辑:姜华 来源: iCSS前端趣闻
相关推荐

2022-03-14 15:07:28

DockerJavaIdea

2022-06-29 07:29:54

WeChatSync工具

2019-07-08 14:46:57

AI 数据人工智能

2020-01-15 08:42:16

TCP三次握手弱网络

2024-05-23 15:20:36

SQLModelPython

2022-03-02 16:05:16

Web前端代码

2013-04-26 16:14:09

视频会议MCU统一通信

2014-12-14 14:43:31

中软JointForce

2013-09-04 18:41:01

Testin云测试

2018-02-27 09:39:00

区块链分布式比特币

2012-08-27 13:30:21

BYOD

2020-12-07 06:22:05

MyBatisPlus开发MP

2016-02-23 11:39:47

Adobe数字化营销

2021-07-01 07:34:09

代码 Python 视频

2023-02-13 08:34:26

Linux键盘快捷键

2016-07-14 14:12:11

华为
点赞
收藏

51CTO技术栈公众号