CSS3变形透视动画总结
1. 总览
使用transform规则可以控制元素的变形透视动画操作,包括控制移动、旋转、倾斜、3D转换等。
属性值
属性值 | 说明 |
---|---|
none | 定义不进行转换。 |
translate(x,y) | 定义 2D 转换。 |
translate3d(x,y,z) | 定义 3D 转换。 |
translateX(x) | 定义转换,只是用 X 轴的值。 |
translateY(y) | 定义转换,只是用 Y 轴的值。 |
translateZ(z) | 定义 3D 转换,只是用 Z 轴的值。 |
scale(x,y) | 定义 2D 缩放转换。 |
scale3d(x,y,z) | 定义 3D 缩放转换。 |
scaleX(x) | 通过设置 X 轴的值来定义缩放转换。 |
scaleY(y) | 通过设置 Y 轴的值来定义缩放转换。 |
scaleZ(z) | 通过设置 Z 轴的值来定义 3D 缩放转换。 |
rotate(angle) | 定义 2D 旋转,在参数中规定角度。 |
rotate3d(x,y,z,angle) | 定义 3D 旋转。 |
rotateX(angle) | 定义沿着 X 轴的 3D 旋转。 |
rotateY(angle) | 定义沿着 Y 轴的 3D 旋转。 |
rotateZ(angle) | 定义沿着 Z 轴的 3D 旋转。 |
skew(x-angle,y-angle) | 定义沿着 X 和 Y 轴的 2D 倾斜转换。 |
skewX(angle) | 定义沿着 X 轴的 2D 倾斜转换。 |
skewY(angle) | 定义沿着 Y 轴的 2D 倾斜转换。 |
perspective(n) | 为 3D 转换元素定义透视视图。 |
注意:
-
重复设置变形操作时只在原来的状态下进行操作,重复设置表示在不同位置进行设定,如果要效果叠加,需要使用transform一起设置,且放在transform上的属性顺序不同效果也不一样。
比如:
transform: rotateX(deg) rotateY(deg); 不同于效果 transform: rotateY(deg) rotateX(deg)
-
行级元素不产生变形效果,也即:transform对行级元素无效。
2. 移动元素
2.1 平面移动
transform: translateX(x)
在X轴方向上进行移动
transform: translateY(y)
在Y轴方向上进行移动
- x为正数:向右移动
- x为负数: 向左移动
- y为正数:向下移动
- y为负数:向上移动
属性值:
-
px
指定移动的具体值
-
%
相对于元素自身大小的倍数,比如:
transform: translateX(-100%)
,表示沿着X轴负方向(左部)移动自身大小一倍的距离。 -
em
相对于元素中设置的字体大小(
font-size
)的倍数距离,font-size: 10px; transform: translateX(1em);
表示沿X轴正方向(右部)移动相对于字体大小1倍的距离10px。
以上两个属性可以简写在一行,也即:
transform: translateX(100px) translateY(100px);
或者采用内置属性值方式进行简写
transform: translate(100px,100px); // 其中第一个属性值为X轴方向的移动距离,第二个属性值为Y轴方向移动的距离。
例子:
<main>
<div></div>
</main>
<style>
main {
width: 200px;
height: 200px;
margin: 100px auto;
border: 1px solid #000;
box-sizing: border-box;
}
div {
width: 50px;
height: 50px;
background: linear-gradient(45deg,#bfc0c1,#bec2bc,#251a15);
// 使div元素位于父元素main中间位置处
transform: translate(150%,150%);
}
</style>
2.2 Z轴方向移动
使用transform: translateZ(z)
可以控制元素在Z轴方向上的移动。由于Z轴是透视轴,没有像X/Y一样的固定尺寸,所以不能使用百分数来进行控制移动距离。
2.3 XYZ轴同时控制
可以使用transform: translate3d(x,y,z)
同时控制元素在x,y,z轴上面的移动。如果某一方向不移动,则置为0。
3. 缩放元素
- scaleX()在X轴上进行缩放
- scaleY()在Y轴上进行缩放
- scaleZ()在Z轴上进行缩放
简写方式
-
scale(x,y)
- 如果是一个值,则表示XY轴缩放系数一致
- 如果是两个值,第一个表示在X轴上的缩放,第二个数值表示在Y轴上的缩放
-
scale3d(x,y,z)
同时对x y z 轴进行缩放处理
属性值:
- 属性值为数值,当属性值大于[-1,1]时,表示元素按照默认的元素中心位置放大相应比例大小,当属性值等于-1/1时,表示元素不变化,当元素在(-1,1)之间的时候,表示元素按照默认的元素中心位置缩小处理。当属性值为0时,元素不显示。
注意:该属性也是在元素原来的位置上进行变形的,也即:如果同时使用了transform: translate(x,y) scale(x,y)
,那么操作只会以最后一次的变形为准,且操作基础为元素没有进行变形操作之前的位置。
以12.2.1的例子来看,12.2.1的例子中通过transform: translate(150%,150%)
移动到了父元素main的中间位置,此时如果再加上transform: scale(3,3)
在x y轴上进行缩放
transform: scale(2,2);
3.1 元素变形原点
元素默认以元素中心进行变形操作。如果需要更改元素变形原点,可以使用transform-orgin
进行设置。
transform-origin
用于更改一个元素变形的原点,默认为center
transform-origin
属性可以使用一个,两个或三个值来指定,其中每个值都表示一个偏移量。 没有明确定义的偏移将重置为其对应的初始值。
如果定义了两个或更多值并且没有值的关键字,或者唯一使用的关键字是center
,则第一个值表示水平偏移量,第二个值表示垂直偏移量。
- 一个值:
- 必须是<length>,<percentage>,或
left
,center
,right
,top
,bottom
关键字中的一个。
- 必须是<length>,<percentage>,或
- 两个值:
- 其中一个必须是<length>,<percentage>,或
left
,center
,right
关键字中的一个。 - 另一个必须是<length>,<percentage>,或
top
,center
,bottom
关键字中的一个。 - 也即如果只使用关键字,需要注意顺序的问题。
- 其中一个必须是<length>,<percentage>,或
- 三个值:
- 前两个值和只有两个值时的用法相同。
- 第三个值必须是<length>。它始终代表Z轴偏移量。
<main>
<div></div>
</main>
<style>
main {
width: 200px;
height: 200px;
margin: 100px auto;
border: 1px solid #000;
box-sizing: border-box;
}
div {
width: 50px;
height: 50px;
background: linear-gradient(45deg,#bfc0c1,#bec2bc,#251a15);
}
main:hover div{
// 定义变形原点为元素的上右部分
transform-origin: top right;
// 元素放大两倍
transform: scale(2);
}
</style>
4. 旋转元素
使用CSS可以控制元素按照不同坐标轴进行旋转。
-
rotateX()
按照X轴进行旋转操作
属性值为:angle,
如果为正,表示顺时针旋转,如果为负表示逆时针旋转
main:hover div { transform: rotateX(90deg); }
当旋转到90deg的时候,元素与Z轴平行,所以会导致从Z轴方向看,看不到元素的情况。
当旋转到89deg的时候,从Z轴方向看,只有一条线存在。
-
rotateY()
与
rotateX()
一致,此时沿着Y轴进行旋转 -
rotateZ()
沿着Z轴进行旋转,效果与沿X/Y平面旋转一样。
-
rotate(x,y)
沿着平面进行旋转
-
rotate3d(x,y,z,angle)
沿着x,y,z旋转,用于3d空间。x y z 严格控制顺序,且值在[0,1]之间,表示旋转轴坐标上面的矢量。
5. 倾斜元素
-
skewX(deg)
沿X方向倾斜,正数表示逆时针方向倾斜,负数表示顺时针方向倾斜。
只要倾斜角度不超过180°,元素都会保持本身的高度,同时为了保持倾斜,元素只能沿着x轴方向拉长本身。
-
skewY(deg)
沿着y方向倾斜,正数表示顺时针倾斜,负数表示逆时针方向倾斜。
-
skew(deg,deg)
设定元素在x y轴上的倾斜
6. 透视
6.1 什么是透视?
我们拍摄的时候,我们拍的是三维空间的物体,但是我们的照片却是二维的、平面的,“透视”其实是指我们在二维平面上再现三维空间的空间感、立体感的观察方法。
透视的特征:
-
近大远小
离得近的物体,其显示就会比较大,如果离得远,那么该物体显示就会比较小且很完整。
-
近宽远窄
类似于近大远小一样,离得越近的物体,其显示的宽度也越大,相反宽度越小
-
近实远虚
距离你近的物体相信你会看到更清晰,远处的就比较模糊。
6.2 CSS3实现透视
CSS3中也可以处理透视。
使用perspective
可以控制元素的透视,加上此属性则该元素/该元素的子元素变可以进行透视显示(在元素在xyz轴上进行变形的时候可以观察到效果)
属性值:px
表示所透视的物体观察的远近,值越大,观察得远,那么离物体就越远,物体显示就会越完整,看的也越全面
transform: perspective(900px) rotateY(60deg);
值越小,观察的比较近,那么可能只能看到元素的某个部分,看的也不是特别全面
transform: perspective(55px) rotateY(60deg);
该属性可以对单个元素设置控制,也可以对元素内部子元素进行透视设置(元素本身不存在透视)
-
对元素本身进行透视设置
transform: perspective(px);
对元素本身进行透视设置,不影响父元素以及子元素
<main> <div>1</div> <div>2</div> </main> <style> main { display: flex; position: relative; box-sizing: border-box; border: 2px solid #fff; } div { width: 200px; height: 200px; margin-right: 10px; background: radial-gradient(at center center,pink,yellow); transform: perspective(900px) rotateY(60deg); display: flex; justify-content: center; align-items: center; font-size: 2em; color: #fff; } </style>
此处给子元素添加了透视,可以看出,只有子元素进行透视显示了
此时如果只给父元素添加透视,如下图,可以看出只有父元素进行透视显示,而子元素没有影响。
-
给子元素添加透视
perspective: 900px;
通过给元素添加此属性,只作用于子元素,而元素本身没有透视效果。
<main> <div>1</div> <div>2</div> </main> <style> main { display: flex; position: relative; box-sizing: border-box; // 给子元素添加透视本身不被影响 perspective: 900px; transform: rotateY(45deg); border: 2px solid #fff; } div { width: 200px; height: 200px; margin-right: 10px; background: radial-gradient(at center center,pink,yellow); transform:rotateY(60deg); display: flex; justify-content: center; align-items: center; font-size: 2em; color: #fff; } </style>
从上图可以看出,在父元素main上添加perspective: 900px
,使得其子元素div有了透视效果,虽然main元素本身沿着Y轴旋转了45deg,但是由于此属性只会作用于子元素上,因此并不会有透视效果,也不会显示出来。
6.3 3d透视
仅仅使用perspective
只能对平面空间中的元素进行透视显示。原因:元素默认在平面空间中。为了观察到立体空间中元素的变化,需要设置元素位于3d空间中。
transform-style
用于设置元素的子元素位于3d空间中还是平面中
属性值
属性值 | 说明 |
---|---|
flat | 设置元素的子元素位于该元素的平面中。(默认) |
perserve-3d | 指示元素的子元素应位于 3D 空间中。- |
因此可以看出,该属性需要设置在父元素上,且作用于子元素身上。
假设不给父元素main添加属性transform-style
,只给其添加透视属性让其可以看到元素移动。
<main>
<div>1</div>
<div>2</div>
</main>
<style>
main {
display: flex;
position: relative;
box-sizing: border-box;
/*给子元素也添加透视 使其可以看到子元素变形*/
perspective: 900px;
/*给当前元素添加透视 可以观察到父元素和子元素一同沿着Y轴旋转45度*/
transform: perspective(900px) rotateY(45deg);
border: 2px solid #fff;
}
div {
width: 200px;
height: 200px;
margin-right: 10px;
background: radial-gradient(at center center,pink,yellow);
/*让子元素在Z轴上移动200px*/
transform: translateZ(200px);
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
color: #fff;
}
</style>
可以看出能大致看出来元素沿着Z轴上移动,但是效果不明显。
此时在main元素上添加transform-style: preserve-3d;
可以看到有明显的移动痕迹。
6.4 透视方位
默认情况下,透视方位为透视元素在x y 轴50%处进行查看元素。
也可以通过perspective-origin
设置透视方位,也就是设置从哪个地方去观测这个元素。(虽然我感觉设置之后和设置之前没有什么区别,用处还带考察)
属性值:
属性值 | 说明 |
---|---|
x-axis | 定义该视图在 x 轴上的位置。默认值:50%(元素本身)。可能的值:left、center、right、length、% |
y-axis | 定义该视图在 y 轴上的位置。默认值:50%。可能的值:top、center、bottom、length、% |
7. 隐藏元素背面
使用 backface-visibility
用于控制是否可以看到元素的背面。
- 一般设置在元素上而不是父元素上
- 需要在父级元素设置
transform-style: preserve-3d
才可以看到效果
属性值 | 说明 |
---|---|
visible | 背面可见 |
hidden | 背面隐藏 |
注:
如果发现元素不能点击,可能是父级设置了 transform-style: preserve-3d
属性,且同级元素设置了3D变化特性,造成对点击元素有遮挡。有以下两种方式解决
- 对变形元素设置
pointer-events: none;
使用其不接受点击事件 - 删除父级的
transform-style: preserve-3d
属性