CSS3之变形
一、CSS3变形简介
CSS3变形是一些效果的集合,比如平移、旋转、缩放和倾斜效果,每个效果都称为变形函数(Transform Function)。
CSS变形允许动态的控制元素,可以在屏幕周围移动,缩小,旋转,或结合所有这些产生复杂的动画效果。
二、变形属性
1、transform属性
transform属性让元素在一个坐标系统中变形,包含一系列变形函数。
语法:transform:none|<transform-function>
可用于内联元素和块元素,默认值为none,表示元素不进行变形;另一个属性值是<transform-function>,表示一个或多个变形函数,以空格分开。
2、transform-function函数
所有的2D变形函数也包含于3D变形规范中。
2D常用的transform-function的功能
函数 | 功能描述 |
---|---|
translate() | 移动元素,可以根据X轴和Y轴坐标重新定位元素位置,两个扩展函数translateX()和translateY() |
scale() | 缩小或放大元素,两个扩展函数scaleX()和scaleY() |
rotate() | 旋转元素 |
skew() | 让元素倾斜,两个扩展函数skewX()和skewY() |
matrix() | 定义矩阵变形,基于X轴和Y轴坐标重新定位元素位置 |
3D常用的transform-function功能
函数 | 功能描述 |
---|---|
translate3d() | 移动元素,用来指定一个3D变形移动位移量 |
scale3d() | 缩放一个元素 |
rotate3d() | 指定元素具有一个三维旋转的角度 |
perspective() | 指定一个透视投影矩阵 |
matrix3d() | 定义矩阵变形 |
3、transform-origin属性
transform-origin属性用来指定元素的中心点位置。变形的原点在元素的中心点,或者是元素X轴和Y轴的50%处。
transform-origin属性值可以是百分比,em、px等具体的值,也可以是top、right、bottom、left和center的关键词。
2D变形中的transform-origin属性可以是一个参数值,也可以是两个参数值。如果是两个参数值,第一个设置水平方向X轴的位置,第二个设置垂直方向Y轴的位置。
3D变形中的transform-origin属性包括了Z轴。
3D变形中transform-origin属性
属性值 | 功能描述 |
---|---|
x-offset | 设置transform-origin水平方向X轴的偏移量,可以是正值(从中心点沿水平方向X轴向右偏移量),也可以是负值(从中心点沿水平方向X轴向左偏移量) |
offset-keyword | 是top、right、bottom、left或center中的一个关键词,用来设置transform-origin偏移量 |
y-offset | 设置transform-origin属性在垂直方向Y轴的偏移量,可以是正值(从中心点沿垂直方向Y轴向下的偏移量),也可以是负值(从中心点沿垂直方向向上的偏移量) |
x-offset-keyword | 是left、right或center中的一个关键词,设置transform-origin属性值在水平X轴的偏移量 |
y-offset-keyword | 是top、bottom和center中的一个关键词,设置transform-origin属性值在垂直Y轴的偏移量 |
z-offset | 设置3D变形中transform-origin远离用户眼睛视点的距离,默认值z=0,取值可以是<length> |
4、transform-style属性
transform-style属性是3D空间一个重要属性,指定嵌套元素如何在3D空间中呈现,主要有两个属性:flat和preserve-3d
语法:transform-style:flat|preserve-3d
- flat:默认值,表示所有子元素在2D平面呈现
- preserve-3d:所有子元素在3D空间呈现
5、perspective属性
perspective属性会设置查看者的位置,并将可视内容映射到一个视锥上,继而投到一个2D视平面上。
语法:perspective:none|<length>
参数说明:
- none:默认值,表示无限的角度来看3D物体,但看上去是平的。
- <length>:接受一个长度单位大于0的值,不能为百分比值。值越大,角度出现的越远,从而创建一个相当低的强度和非常小的3D空间变化;反之,值越小,角度出现的越近,从而创建一个高强度的角度和大型的3D变化。
示例图:
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3变形</title>
<style>
.wrapper {
width: 50%;
float: left;
}
.cube {
font-size: 4em;
width: 2em;
margin: 1.5em auto;
transform-style: preserve-3d;
transform: rotateX(-40deg) rotateY(32deg);
}
.side {
position: absolute;
width: 2em;
height: 2em;
background: rgba(255, 99, 71, 0.6);
border: solid 1px rgba(0, 0, 0, 0.5);
color: white;
text-align: center;
line-height: 2em;
}
.front {
transform: translateZ(1em);
}
.top {
transform: rotateX(90deg) translateZ(1em);
}
.right {
transform: rotateY(90deg) translateZ(1em);
}
.bottom {
transform: rotateX(-90deg) translateZ(1em);
}
.left {
transform: rotateY(90deg) translateZ(1em);
}
.back {
transform: rotateY(-180deg) translateZ(1em);
}
.w1 {
perspective: 100px;
}
.w2 {
perspective: 1000px;
}
</style>
</head>
<body>
<div class="wrapper w2">
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w1">
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
</body>
</html>
perspective的简单结论:
- perspective取值为none或不设置,没有3D空间。
- perspective取值越小,3D效果就越明显,也就眼睛越靠近真3D;
- perspective的值无穷大,或值为0时与取值为none效果一样
perspective()函数与perspective属性:
perspective函数也可以激活3D空间,不同之处:perspective用在舞台元素上(变形元素的父元素);perspective()函数用在当前变形元素上。
6、perspective-origin属性
perspective-origin属性主要用来决定perspective属性的源点角度,实际上设置了X轴和Y轴位置,在该位置观看者好像在观看该元素的子元素。
语法:perspective-origin:<percentage>|<length>|left|center|right|top|bottom
该属性默认值为50% 50%
(就是center),可以设置为一个值,也可以设置为两个长度值。
第一个长度值指定相对于元素的包含框的X轴上的位置,可以是长度值、百分比或以下关键词之一:
- left:在包含框的X轴方向长度的0%
- center:中间点
- right:长度的100%
第二个长度值指定相对于元素的包含框的Y轴上的位置,可以是长度值、百分比或以下关键词之一:
- left:在包含框的X轴方向长度的0%
- center:中间点
- right:长度的100%
注意:为了指转换子元素变形的深度,perspective-origin属性必须定义在父元素上。perspective-origin属性需要与perspective属性结合起来使用,以便将视点移至元素的中心以外的位置。
示例图:
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3变形</title>
<style>
.wrapper {
width: 30%;
display: inline-block;
padding-bottom: 1em;
}
.wrapper h1 {
text-align: center;
font-size: 1.5em;
}
.cube {
font-size: 2em;
width: 2em;
height: 2em;
margin: .5em auto;
transform-style: preserve-3d;
perspective: 250px;
}
.w1 .cube {
perspective-origin: top left;
}
.w2 .cube {
perspective-origin: top;
}
.w3 .cube {
perspective-origin: top right;
}
.w4 .cube {
perspective-origin: left;
}
.w5 .cube {
perspective-origin: center;
}
.w6 .cube {
perspective-origin: right;
}
.w7 .cube {
perspective-origin: bottom left;
}
.w8 .cube {
perspective-origin: bottom;
}
.w9 .cube {
perspective-origin: bottom right;
}
.side {
position: absolute;
width: 2em;
height: 2em;
background: rgba(255, 99, 71, 0.6);
border: solid 1px rgba(0, 0, 0, 0.5);
color: white;
text-align: center;
line-height: 2em;
}
.front {
transform: translateZ(1em);
}
.top {
transform: rotateX(90deg) translateZ(1em);
}
.right {
transform: rotateY(90deg) translateZ(1em);
}
.left {
transform: rotateY(-90deg) translateZ(1em);
}
.bottom {
transform: rotateX(-90deg) translateZ(1em);
}
.back {
transform: rotateY(-180deg) translateZ(1em);
}
</style>
</head>
<body>
<div class="wrapper w1">
<h1><code>top left</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w2">
<h1><code>top</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w3">
<h1><code>top right</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w4">
<h1><code>left</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w5">
<h1><code>center</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w6">
<h1><code>right</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w7">
<h1><code>bottom left</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w8">
<h1><code>bottom</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
<div class="wrapper w9">
<h1><code>bottom right</code></h1>
<div class="cube">
<div class="side front">1</div>
<div class="side back">6</div>
<div class="side right">4</div>
<div class="side left">3</div>
<div class="side top">5</div>
<div class="side bottom">2</div>
</div>
</div>
</body>
</html>
7、backface-visibility属性
backface-visibility决定元素旋转背面是否可见。对于未旋转的元素,该元素的正面面向观看者。当其Y轴旋转约180度时会导致元素的背面面对观众。
语法:backface-visibility:visible|hidden
- visible:默认值,反面可见
- hidden:反面不可见
三、CSS3 2D 变形
1、2D位移
在这里 translate是一种方法,将元素向指定的方向移动。可以理解为,使用translate()函数可以把元素从原来的位置移动,而不影响在X、Y轴上任何组件。
语法:translate(tx)
或translate(tx,ty)
translate()函数可以取一个值,也可以取两个值。
参数说明:
- tx:代表X轴(横坐标)移动的向量长度,为正值时,元素向X轴右方向移动;为负值时,元素向X轴左方向移动。
- ty:代表Y轴(纵坐标)移动的向量长度,为正值时,元素向Y轴下方向移动;为负值时,元素向Y轴上方向移动。如果ty没有显示设置时,相当于ty=0.
结合起来,translate()函数移动元素主要有以下三种情况:
- 水平移动:向右移动translate(tx,0),向左移动translate(-tx,0)。
- 垂直移动:向上移动translate(0,-ty),向下移动translate(0,ty)。
- 对角移动:右下角移动translate(tx,ty)、右上角移动translate(tx,-ty)、左上角移动translate(-tx,-ty),左下角translate(-tx,ty)。
单独一个方向移动对象的方法:
- translateX:水平方向移动一个对象。对象只向X轴进行移动。为正值,对象向右移动;为负值,对象向左移动。
- translateY:垂直方向移动一个对象。对象只向Y轴进行移动。为正值,对象向下移动;为负值,对象向上移动。
2、2D缩放
缩放函数scale()让元素根据中心原点对对象进行缩放,默认值为1。0.01~0.99之间的值使一个元素缩小;大于等于1.01的值使元素显得更大。
语法:scale(sx)
或scale(sx,sy)
可以接受一个值,也可以接受两个值,只有一个值时,第二个值默认与第一个值相等。
- sx:指定横向坐标(X轴)方向的缩放量。如果值为0.01~0.99之间的值使对象在X轴方向缩小;如果值为大于等于1.01的值使对象在X轴方向放大。
- sy:指定纵坐标(Y轴)方向的缩放量。如果值为0.01~0.99之间的值使对象在Y轴方向缩小;如果值为大于等于1.01的值使对象在Y轴方向放大。
单独一个方向缩放对象的方法:
- scaleX:相当于scale(sx,1),表示元素只在X轴缩放元素,默认值是1;
- scaleY:相当于scale(1,sy),表示元素只在Y轴缩放元素,默认值是1;
在scale()函数中除了可以取正值,还可以取负值,只不过取负值时,会先让元素反转再进行缩放。
scale()函数对元素进行缩放时,都是以元素的中心为基点,但可以通过transform-origin改变元素的基点。
3、2D旋转
rotate()函数通过指定角度对元素对象的原点指定一个2D旋转。如果为正值,元素相对原点中心顺时针旋转;如果为负值,元素相对原点中心逆时针旋转。
语法:rotate(a)
,只接受一个值,代表旋转的角度值。
示例图:
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3变形</title>
<style>
.rot{
width:5em;
height: 5em;
border:solid rgba(0,0,0,0.5) 1px;
background-color:orange;
margin:5em 2em;
display: inline-block;
}
.rot45deg{
transform:rotate(45deg);
}
.rot-45deg{
transform:rotate(-45deg);
}
</style>
</head>
<body>
<div class="rot rot45deg">顺时针旋转45度</div>
<div class="rot">原图</div>
<div class="rot rot-45deg">逆时针旋转45度</div>
</body>
</html>
4、2D倾斜
skew()函数可以将一个对象以其中心位置围绕着X轴和Y轴按照一定的角度倾斜。与rotate()只会旋转,不会改变元素的形状,skew函数会改变元素的形状。
语法:skew(ax)
或skew(ax,ay)
如果为设置值,默认为0。
- ax:指定元素水平方向(X轴)倾斜的角度;
- ay:指定元素垂直方向(Y轴)倾斜的角度;
单独一个方向倾斜对象的方法:
- skewX():相当于skew(ax,0)和skew(ax)。skewX()使元素以其中心为基点,在水平方向倾斜;
- skewY():相当于skew(0,ay)。skewY()使元素以其中心为基点,在垂直方向倾斜;
默认值情况下,skew()函数以元素的原中心点对元素进行倾斜变形,但可以通过transform-origin属性重新设置元素基点对元素进行倾斜变形。
5、2D矩阵
变形中的矩阵函数matrix()不常用。在CSS3中的变形都可以使用matrix()函数代替。
四、CSS3 3D变形
使用三维变形,可以改变元素在Z轴位置。三维变换使用基于二维变换的相同属性。
3D变换主要包括以下几种功能函数:
- 3D位移:包括translateZ()和translate3d()两个功能函数;
- 3D旋转:包括rotateX()、rotateY()、rotateZ()和rotate3d()四个功能函数;
- 3D缩放:包括scaleZ()和scale3d()两个功能函数;
- 3D矩阵:和2D变形一样,也有一个3D矩阵功能函数matrix3d()。
1、3D位移
translate3d()函数的语法:translate3d(tx,ty,tz)
参数说明:
- tx:代表横坐标位移向量的长度;
- ty:代表纵坐标位移向量的长度;
- tz:代表Z轴位移向量的长度。不能为百分比值。
translateZ()函数的语法:translateZ(t)
,取值t指的是Z轴的向量位移长度。使用TranslateZ()可以让元素在Z轴进行位移。为负值时,元素在Z轴越移越远,导致元素变得较小;为正值时,元素在Z轴越移越近,导致元素变得较大。
translateZ()函数在实际使用中等同于translate3d(0,0,tz)。
2、3D缩放
当scale3d()中X轴和Y轴同时为1,即scale3d(1,1,sz),效果等同于scaleZ(sz)。
scale3d语法:scale3d(sx,sy,sz)
,可以让元素在Z轴上按比例缩放。默认值为1,当值大于1时,元素放大;当值小于1大于0.01时,元素缩小。
scaleZ()语法:scaleZ(s)
,取值s指定每个点Z轴的比例。scaleZ(-1)定义了一个原点在Z轴的对称点。
提示:scaleZ()和scale3d()函数单独使用时没有任何效果,需要配合其它变形函数一起使用时才有效果。
3、3D旋转
在三维空间里,使用rotateX()、rotateY()和rotateZ()函数让一个元素围绕X、Y、Z轴旋转。
语法:rotateX(a)|rotateY(a)|rotateZ(a)
,其中a指的是旋转角度值,可以是正值,也可以是负值。为正值,元素顺时针旋转;为负值,元素逆时针旋转。
rotate3d()函数也可以让元素在三维空间中旋转,轴的旋转是由一个[x,y,z]向量并经过元素原点。语法:rotate3d(x,y,z,a)
参数说明:
- x:0~1的数值,用来描述元素围绕X轴旋转的矢量值;
- y:0~1的数值,用来描述元素围绕Y轴旋转的矢量值;
- z:0~1的数值,用来描述元素围绕Z轴旋转的矢量值;
- a:角度值,用来指定元素在3D空间旋转的角度。正值时,元素顺时针旋转;负值时,元素逆时针旋转。
当x、y、z取不同值时,和前面的三个旋转函数功能等同:
- rotateX(a)函数功能等同于rotate3d(1,0,0,a);
- rotateY(a)函数功能等同于rotate3d(0,1,0,a);
- rotateZ(a)函数功能等同于rotate3d(0,0,1,a);
4、3D矩阵
语法:matrix3d(sx,0,0,0,0,sy,0,0,0,0,sz,0,0,0,0,1)
提示:倾斜是二维变形,不能在三维空间变形,元素可能会在X轴和Y轴倾斜,然后转化为三维,但它们不能在Z轴倾斜。
5、多重变形
在CSS3中,不管是2D变形还是3D变形,都可以使用多重变形,它们之间使用空格分隔,语法:transform:<transform-function>|<transform-function>
其中,transform-function是指CSS3中的任何变形函数。
示例1:2D多重变形制作立方体
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3变形</title>
<style>
@keyframes spin{
0%{transform:rotateY(0deg)}
100%{transform:rotateY(360deg)}
}
.stage{
width:300px;
height: 300px;
float: left;
margin:15px;
background: url(img/background.png) no-repeat center center;
background-size:100% 100%;
position: relative;
perspective: 1200px;
}
.container{
position: relative;
height: 230px;
width:100px;
top:50%;
left: 50%;
margin:-100px 0 0 -50px;
transform-style: preserve-3d;
}
.container:hover{
animation: spin 5s linear infinite;
}
.side{
font-size:20px;
font-weight: bold;
height: 100px;
line-height: 100px;
color:#fff;
position: absolute;
text-align: center;
text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
text-transform: uppercase;
width:100px;
}
.top{
background:#9acc53;
transform:rotate(-45deg) skew(15deg,15deg);
}
.left{
background:#8ec63f;
transform:rotate(15deg) skew(15deg,15deg) translate(-50%,100%);
}
.right{
background:#80b239;
transform:rotate(-15deg) skew(-15deg,-15deg) translate(50%,100%);
}
</style>
</head>
<body>
<div class="stage s1">
<div class="container">
<div class="side top">1</div>
<div class="side left">2</div>
<div class="side right">3</div>
</div>
</div>
</body>
</html>
示例图2:3D多重变形制作立方体
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3变形</title>
<style>
@keyframes spin{
0%{transform:rotateY(0deg)}
100%{transform:rotateY(360deg)}
}
.stage{
width:300px;
height: 300px;
margin:15px auto;
background: url(img/background.png) no-repeat center center;
background-size:100% 100%;
position: relative;
perspective: 300px;
}
.container{
position: absolute;
height: 230px;
width:100px;
top:50%;
left: 50%;
margin:-100px 0 0 -100px;
transform:translateZ(-100px);
transform-style:preserve-3d;
}
.container:hover{
animation: spin 5s linear infinite;
}
.side{
background:rgba(142,198,63,0.3);
border:2px solid #8ec63f;
font-size: 60px;
font-weight: bold;
color:#fff;
height: 196px;
line-height: 196px;
position: absolute;
text-align: center;
text-shadow:0 -1px 0 rgba(0,0,0,0.2);
text-transform:uppercase;
width:196px;
}
.front{
transform:translateZ(100px);
}
.back{
transform:rotateX(180deg) translateZ(100px);
}
.top{
transform:rotateX(90deg) translateZ(100px);
}
.left{
transform:rotateY(-90deg) translateZ(100px);
}
.right{
transform:rotateY(90deg) translateZ(100px);
}
.bottom{
transform:rotateX(-90deg) translateZ(100px);
}
</style>
</head>
<body>
<div class="stage s1">
<div class="container">
<div class="side front">1</div>
<div class="side back">2</div>
<div class="side left">3</div>
<div class="side right">4</div>
<div class="side top">5</div>
<div class="side bottom">6</div>
</div>
</div>
</body>
</html>