所谓元素转换,其实就是对元素的坐标在二维或三维空间上做矩阵换算。根据换算的结果,又分成了多种转换类型。但无论是哪一种,都不影响元素在页面上的物理空间,只改变元素的视觉效果。也就是说,比如元素缩放、旋转都不影响周围其他元素的布局。有些开发者喜欢用平移做元素居中效果,其实非常不妥,因为元素原来的物理空间还在那里,控制起来不轻松。
另外,转换属性(transform)只有一个,因此,转换类型不能叠加。也就是说,如果之前做了旋转(rotate),如果再做平移(translate),旋转效果就会消失。如果既想平移,又想旋转,必须使用matrix方法。
设置转换原点
转换原点在缩放、倾斜和旋转中很重要,具体参考各转换。转换原点默认是元素的中心,即transform-origin: 50% 50% 0。
转换矩阵
在二维空间中,转换矩阵是一个3x3矩阵;在三维空间中,是4x4矩阵。下面这个公式左边的2x2矩阵,就是一个转换矩阵,因为是2x2的,所以只能做缩放、旋转、倾斜,不能做平移。因此,实际上,浏览器使用的是3x3或4x4的矩阵。
矩阵右边(x,y)是原坐标,(ax+cy, bx+dy)是转换后的坐标。
CSS 2D transforms
Translating –平移
平移和position:relative效果相似,不影响元素的物理空间位置,只影响视觉空间位置,也就是说虽然看起来元素已经离开了原来的位置,但它所占的物理空间依然是原来位置,并且只在原位置上对其他元素有影响。
平移的距离即可以使用像素值,也可使用百分比。如果是百分比,则盒子的宽高(width & height)决定了百分比的最终值,其中,水平位移取决于盒子宽度,垂直位移取决于盒子高度。
transform: translate(50px, 100px);
transform: translateX(50px);
transform: translateY(50%);
transform: translateY(100px);
在不支持的浏览器中,使用position:relative,然后通过top和left即可以调整。
Scaling – 缩放
缩放即指放大缩小,但效果只相当于用放大镜看,元素所占的物理空间依然没有变化。因此,放大或缩小元素,不影响周围其他元素的布局。
当然,放大缩小也是有方向的,因为原点默认是中心点,所以默认是中心向四周放大。如果要修改放大缩小方向,需要修改transform-origin。
如果有一个值为0,等价于设置width或height为0;如果scale只接受了一个参数,表示x和y方向缩放同样倍数。
transform: scale(2.5);
transform: scale(2, 1);
transform: scaleX(2);
transform-origin: left top;
Skewing – 倾斜
倾斜有向X轴倾斜和向Y轴倾斜,其中向X轴倾斜在视觉上是逆时针扭曲,向Y轴倾斜在视觉上是顺时针扭曲。因此,如果X轴和Y轴倾斜角度相同,而正负相反,则等同于旋转(rotate),旋转方向由第一个值决定。
一个维度倾斜的时候,另一个维度的大小保持不变。比如,skew(30deg),表示向X轴方向倾斜30度,但元素的纵轴高度保持不变。
transform: skew(30deg);
transform: skew(30deg, 0);
transform: skew(30deg, -30deg);
注意:倾斜没有3D转换。
Rotating – 旋转
二维旋转其实就是在三维空间上绕Z轴旋转,旋转方向为顺时针方向,原点默认是元素的中心点,因为transform-origin的默认值为transform-origin:50% 50% 0。如果要把左上角设为原点,则应该设置transform-origin为transform-origin: 0 0 0。
transform: rotate(30deg);
CSS 3D transform
以下提到的3D转换,在IE9都不支持。
Translating -平移
3D平移和2D平移没有什么差别,最后一个z轴坐标没有任何影响。注意z轴坐标和z-index完全是两码事,互不影响。
transform: translate3d(50px, 100px, 0);
Scaling - 缩放
3D缩放需要注意的是缩放原点,原点决定了缩放方向,对视觉效果影响很大。
Rotating – 旋转
转换方法rotate3d()、rotateX、rotateY、rotateZ理论上都只使用于三维空间,比如rotateX和roateY在二维空间就中无效。但rotate3d和rotateZ却可以做XY二维空间换算,比如,如果rotate3d(0, 0, 1, 10deg)就可以让元素在二维空间上顺时针旋转10度,同理,rotateZ(10deg)也可以让元素在二维空间上顺时针旋转10度。需要注意的是,X和Y轴不应该有值,否则就是按三维空间计算了,这会导致转换失败。
transform: rotate3d(0, 0, 1, 30deg);
注意:ie9不支持rotate3d、rotateX、rotateY、rotateZ方法。
Perspective - 透视
透视表示z=0平面和用户之间的距离,透视值越大,则离用户越近,看起来也越大;透视值越小,则离用户越远,看起来也要越小。
透视只在三维空间有效,有点像z-index。
transform: perspective(1);
兼容性
早版本的Firefox、Chrome、Opera或IE,分别使用一下前缀兼容:
-moz-transform: rotate(30deg);
-o-transform: rotate(30deg);
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
IE
IE的BasicImage滤镜支持四个旋转值:0,1, 2, 和 3分别对应0, 90, 180和 270度。
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
另外,IE有一个矩阵滤镜,也可以做到CSS的transform效果,具体参考:
https://msdn.microsoft.com/en-us/library/ms533014%28VS.85,loband%29.aspx。
如果自己算不来,这里还有一个工具可以帮助你计算:
http://www.useragentman.com/IETransformsTranslator/。注意,用高版本的IE在兼容模式下不一定能看这些效果,需要真实的该版本IE才能看到。