Skip to content

scale 和前面的 rotate 一样,也是 transform 的一个变换函数,这个函数的功能为缩放。

这个函数允许我们传入两个参数,第一个参数为 x 轴的伸缩值,第二个参数为 y 轴的伸缩值。

![recording 4](/notes-assets/04.CSS3/assets/recording 4.gif)

可以看到,第一个参数变大的同时,盒子被 x 轴拉伸,第二个参数变大的同时,盒子被 y 轴拉伸。同样,如果放大的比例小于 1,那么盒子就会收缩。

如果只写一个参数,表示横向纵向拉伸同样的比例,例如 scale(3) 等价于 scale(3,3)

值得注意的是,和前面一样,任何变换函数本质上变换的都是坐标轴,而元素则是跟随坐标轴一同变换的,换句话说,可以理解为元素是根据坐标轴进行渲染的,transform 的变换函数通过变换坐标轴最终改变了元素的渲染效果,即元素样式的变换只是坐标轴变换的一个附加作用。包括前面的 rotate,也是通过变换坐标轴实现的。这里的 scale 本质上是对坐标轴进行伸缩,第一个参数为 x 的伸缩量,比如将第一个参数传入 2,那么此时 x 轴一个单位的长度就和原来两个单位长度一样,y 轴同理。

![recording 5](/notes-assets/04.CSS3/assets/recording 5.gif)

可以看到,不管我的 scale 如何伸缩,右下角的盒模型宽高是固定不动的,也就是说这个盒子的宽高本质上没有变化,变化的只是它的坐标轴,而渲染层面是根据坐标轴变换的,举个例子,例如 scale(2,1),这个函数会将元素横向拉伸到 2 倍,本质上其实是把 x 坐标轴拉长为了原来的两倍,即原来坐标轴 x 轴和 y 轴中 1 像素渲染出来就是真实的 1 像素,但是此时把 x 拉伸了一倍,此时横向 1 像素的渲染效果就变成了 2 像素,最终就会导致发生了这样的变化。

scale 函数是可以叠加的 :transform:scale(0.5,0.5) scale(2,2) ,此时先将 x 和 y 坐标都缩小到原来的一半,再扩大两倍,最终效果其实就是扩大了 0.5*2=1 倍,也就是毫无变化。注意,后一个 scale 是基于前一个 scale 变化基础之上进行变换的,第一个 scale 是会影响第二个 scale 效果的,并不是直接覆盖。

scale 函数内可以传入负数,这个很有意思,如果传入负数,那么盒子会直接翻转

注意,所有 transform 的函数使用的都是同一个坐标轴,这也就意味着,如果我使用 rotate 将坐标轴旋转之后,scale 就会按照旋转之后的坐标轴去放缩。

![Pasted image 20240128081041](/notes-assets/04.CSS3/assets/Pasted image 20240128081041.png)

可以看到,我先将坐标轴旋转 45 度,再放缩,此时就是按照新坐标轴放缩的,就不再是按照原来横向放缩了。

![Pasted image 20240128081222](/notes-assets/04.CSS3/assets/Pasted image 20240128081222.png)

但如果我是这样,先放缩,再旋转,效果就不一样了,按照前面的介绍,不管 scale 和 rotate 哪个在前,本质上效果都应该一样,都是先将坐标轴旋转 45 度,再将 x 坐标拉伸为原来 2 倍。但实际上并不是这么回事。虽然第二步的 rotate 改变了坐标系,但实际上第一个 scale 的变换还是基于原来的坐标系。在第一个 scale 执行的时候,x 坐标轴还是横向的,所以会进行横向拉伸,哪怕第二个 rotate 将坐标轴旋转了,第一个 scale 依然是横向拉伸,而不是基于旋转之后的坐标轴。读者可以这么去理解,前面的变换会影响后面的变换,后面的变换并不会影响前面已经发生的变换。

实际上 transform 的所有变换函数本质上都是矩阵。或者说 transform 本身就是矩阵的一个应用,矩阵本身是不具有交换性的,所以变换顺序会影响最后的结果。而矩阵乘法的运算顺序是从前往后的,所以后面的变换实际上是在前面变换的基础之上的,并不会影响到前面的变换。

这种拉伸效果也是支持 3D 的,首先,scale(a,b) 就相当于 scaleX(a) scaleY(b),这个其实很好理解,scaleX 就是拉伸 x 轴,scaleY 就拉伸 y 轴,这两个配合起来就可以实习 scale 的等价效果。

而 3d 版的 scale,则是 scaleZ 函数,这个函数实际是就是 z 轴的拉伸。但是这个函数很难看到效果,因为我们元素的厚度可以认为是 0,不管 z 轴怎么拉伸最终都是 0,所以为了显示出 z 轴的效果,就得在 rotate 前面添加,如果我最开始就写上 scaleZ 函数,就会在当前的 z 轴进行拉伸,而后面再将坐标轴进行旋转,这个拉伸方向依然不会变。

![recording 6](/notes-assets/04.CSS3/assets/recording 6.gif)

可以看到,这里也能验证,哪怕我 rotateX 已经旋转了坐标轴,前面的 scaleZ 也是基于以前的坐标轴,也就是朝着我屏幕的方向纵向拉伸。

scale 函数可以看做是 scaleX 和 scaleY 的组合属性,而 scale3d 可以看做是 scaleX,scaleY,scaleZ 三个属性的组合属性。

以笔记为镜,可以知得失