CSS 变形

变形是一些效果的集合,主要是移动、缩放、旋转和倾斜4 种基本操作,也可通过matrix矩阵来实现更复杂的效果。

配合过渡和动画的知识,可以替代大量之前只能靠flash才能实现的效果。

transform 可以实现2D 和 3D两种效果。                                           // 变形的副作用?!


2D 效果

2D效果,涉及的属性主要有:变形原点(transform-origin)和变形函数(transform)。

[1] 变形原点 transform-origin:变形操作所依据的基点,默认为元素的中心点。

transform-origin:x轴 y轴 z轴     // 不考虑3维情况下,变形原点是由x轴和y轴共同决定的,z轴默认为0
如,transform-origin:left top;    
   transform:rotate(45deg);        // 以左上角为原点,顺时针旋转45度

// 应用于非inline元素;IE9-不支持,safari3.1-8、android2.1-4.4.4、IOS3.2-8.4需加前缀,其他更高版本浏览器可使用标准写法

   x轴: left | center | right | <length> | <percentage> 
   y轴: top | center | bottom | <length> | <percentage>

       具体来讲:
         1. 关键字方面 — x轴 left(0%) center(50%) right(100%),y轴同理;
         2. 数值 — x轴数值表示在x轴上离0点(元素边框外侧左上角)的偏移量,y轴同理;
         3. 百分比 — x轴的百分比是相对于元素的宽度和(width+横向padding+横向border),即包含块的宽度;y轴同理;
         4. 单个值 — 当只有一个值的时候,默认第二个值为center;

[2] 变形函数 transform:一系列变形函数(位移、缩放、旋转、倾斜)的集合                   // 矩阵 martrix?!

需要注意的是,位移、缩放、旋转和倾斜这四个操作中,除了位移与变形原点无关,其余三个都与变形原点有关。

transform:none(默认) | <transform-function>+        // transform中出现多个变形函数时用空格分隔,并且按照从前往后的顺序执行
<transform-function>: translate | scale | rotate | skew | matri

[ 移动 translate ]可以使元素从原来的位置上移动指定的位移。

// 发生位移后,元素的x轴和y轴也一并移动,若元素再进行其他变形操作,则要沿着改变后的x轴和y轴进行变形。

transform:translate(x[,y]?)            // 当y不存在时,相当于y=0
如,transform:translate(30px,30px);     // 水平方向和垂直方向同时移动(x轴和y轴同时移动)

   位移函数还可以接受百分比,其中x%是相对于元素水平方向的宽度和,y%同理;但是,IE10浏览器有bug,元素的位移函数的百分比是相对于元素的可视宽高(不包括边框)而言的。

   也可以分开写:
   translateX(x) 相当于 translate(x,0)      // 仅水平方向移动(x轴移动)
   translateY(y) 相当于 translate(0,y)      // 仅垂直方向移动(y轴移动)

// 位移函数相当于matrix(1,0,0,1,x,y)

// 代码示例:定位的盒子居中对齐

.box{
   width:499.99px;
   height:400px;
   background-color:pink;
   position:absolute;
   left:50%;
   top:50%;
   transform:translate(-50%,-50%);    // 移动自身的一半
}

[ 缩放 scale ]可以让元素根据变形原点进行缩放,默认值为1。

// 元素被缩放后,若要进行位移:

  • 数值类型的位移要乘以该缩放比例;
  • 百分比类型的位移值要乘以原来的宽度或高度和,转化成数值类型后,在乘以缩放比例;
transform:scale(x,[,y]?)           // 当y不存在时,相当于y=x;当x或y的值为负值时,元素先翻转再缩放

// 缩放的取值,默认为1。
// 当值设置为0.01~0.99之间的任何值时,作用是使一个元素缩小;而任何大于或等于1.0的值,作用是让元素变大。

   也可以分开写:
   scaleX(x) 相当于 scale(x,1)       // 表示元素在x轴方向上的缩放比例
   scaleY(y) 相当于 scale(1,y)       // 表示元素在y轴方向上的缩放比例

// 缩放函数相当于matrix(x,0,0,y,0,0)

[ 倾斜 skew ]可以让元素以其变形原点围绕x轴和y轴进行一定角度的倾斜。

// 元素倾斜后,x轴和y轴发生倾斜,若元素要进行其他变形操作,则沿着倾斜后的x轴和y轴进行变形。

transform:skew(xdeg,[,ydeg]?)      // 可以为负值;当y不存在时,相当于y=0
    
       x>0时,表示y轴向x轴正方向倾斜;x<0时,表示y轴向x轴负方向倾斜
       y>0时,表示x轴向y轴正方向倾斜;y<0时,表示x轴向y轴负方向倾斜

   可以分开写:
   skewX(x) 相当于 skew(x,0)   // 表示y轴向x轴倾斜的角度
   skewY(y) 相当于 skew(0,y)   // 表示x轴向y轴倾斜的角度

// 倾斜函数相当于matrix(1,tany,tanx,1,0,0)

[ 旋转 rotate ] 可以让元素通过指定的角度(deg)根据变形原点进行顺时针旋转,默认为 0deg。

// 元素旋转后,元素的x轴和y轴也随之旋转。若元素要进行其他变形操作,则沿着旋转后的x轴和y轴进行变形。

transform:rotate(Ndeg)    // 旋转不会改变元素的形状,涉及到旋转的2d效果函数也只有一个

   当N为正数时,元素进行顺时针旋转;当N为负数时,元素进行逆时针旋转。

// 旋转函数相当于matrix(cosN,sinN,-sinN,cosN,0,0)

3D 效果

3D效果,涉及的属性有(变形原点、透视、变形函数、背景可见和变形风格):

transform-origin、perspective、perspective-origin、transform、backface-visibility、transform-style。


[ 基础知识 - 坐标轴 ]3D效果和2D效果最大的不同在于其参考的坐标轴的不同,2d是平面的,3d是立体的。

也就是说,2D效果只有x轴和y轴,而3D效果则是x、y、z三条轴组成的立体空间,其正向分别指向右、下和屏幕外。


[1] 变形原点 transform-origin:2d效果没有z轴,所以默认为0,而3d效果的z轴是一个可以设置的变量。

transform-origin: x轴 y轴 z轴        // 初始值: 50% 50%;应用于非inline元素

// IE9-不支持,safari3.1-8、android2.1-4.4.4、IOS3.2-8.4都需要添加前缀,其他更高版本浏览器可使用标准写法

   x轴: left | center | right | <length> | <percentage>   
   y轴: top | center | bottom | <length> | <percentage>    // 百分比参照物是元素自身的宽度和或高度和
   z轴: <length>         // z轴只能设置长度值

[2] 透视 perspective:透视是3D效果中最重要的内容,如果不设置透视,元素的3D效果将无法实现。

[理解透视原理?!深入了解透视,需要熟悉 — 观察者、被透视元素和变形元素这几个概念。

  • 变形元素:顾名思义,就是进行transform3D变形的元素。
  • 观察者:浏览器模拟出的用来观察被透视元素的一个没有尺寸的点,从观察者的透视原点发出视线。
  • 被透视元素(被观察者观察的元素):根据属性设置的不同,可能是变形元素本身,也可能是父级 / 祖先元素。

// 激活透视的方式

在3D效果中,激活透视属性的方式有两种透视属性?!或 透视函数):

perspective: none | <length>;
   // 使用perspective(视距)属性,结合透视原点,但只能用在变形元素的父级或祖先级上;
 perspective-origin:x轴 y轴;    // 默认为元素中心点;同2d效果的变形原点值

  或

transform: perspective(<length>) method(p) method(p) ...;
  // 使用透视函数perspective(),它是transform变形函数的一个属性值,应用于变形元素本身。

[ 透视函数 ] 由于透视原点perspective-origin只能设置在设置了perspective透视属性的元素。 若为元素设置透视函数perspective(),则透视原点不起使用,观察者使用默认位置,即元素中心点对应的平面上。

transform: perspective(<length>)        // (<length>)的参数只能是长度值,长度值只能是正数

由于transform属性是从前向后的顺序解析属性值的,所以:
   一定要把perspective()函数写在其他变形函数前面,否则将没有透视效果。

[3] 变形函数:上面介绍了2D效果,而3D效果也类似,包括位移、旋转和缩放,但没有倾斜。

倾斜skew()是二维变形,不能在三维空间变形,元素可能会在x轴和y轴倾斜,但不能在z轴倾斜。


[ 3D移动 ] 主要包括traslateZ()和translate3d()

translate3d(x,y,z)     // 其中,x和y可以是长度值,也可以是百分比,百分比是相对于其本身元素水平方向的宽度和垂直方向的高度和;
                       // z只能设置长度值

traslateZ(z) 相当于 translate3d(0,0,z)      // 常用-webkit-transform: translateZ(0);来开启硬件加速

// 3d位移函数相当于matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,x,y,z,1)

[ 3D缩放 ] 主要包括scaleZ()和scale3d()

scale3d(x,y,z)       // 默认值为scale3d(1,1,1),当参数为负值时,先翻转再缩放

scaleZ(z) 相当于 scale3d(1,1,z)

需要注意的是:scaleZ()和scale3d()单独使用时没有任何效果

// 3d缩放函数相当于matrix3d(x,0,0,0,0,y,0,0,0,0,z,0,0,0,0,1)

[ 3D旋转 ] 主要包括rotateX()、rotateY()、rotateZ()、rotate3d()

rotate3d(x,y,z,Ndeg)

x、y、z分别用来描述围绕x、y、z轴旋转的矢量值,最终变形元素沿着由(0,0,0)和(x,y,z)这两个点构成的直线为轴,进行旋转。
当N为正数时,元素进行顺时针旋转;当N为负数时,元素进行逆时针旋转

// safari浏览器不支持keyframes中改变rotate3d()

   rotateX(Ndeg)相当于rotate3d(1,0,0,Ndeg)
   rotateY(Ndeg)相当于rotate3d(0,1,0,Ndeg)
   rotateZ(Ndeg)相当于rotate3d(0,0,1,Ndeg)

[4] 背景可见 backface-visibility: 设置元素背面是否可见

元素的背面默认是可见的。但有时需要让元素背面不可见,这就要用到属性backface-visibility。

backface-visibility:visibile(可见,默认) | hidden(不可见)

[5] 变形风格 transform-style:允许变形元素及其子元素在3d空间中呈现

// 设置perspective后,默认元素内部的子元素是扁平化,即2D效果。

transform-style: flat | preserve-3d
    flat:默认值,扁平化,表示2d平面;
    preserve-3d:表示3d空间

// 当设置了 overflow:非visible 或 clip:非auto 时,transform-style:preserve-3d 失效。