前言
- 请简述一下 CSS3 中新增的变形如何使用?
变形介绍
CSS2.1 中的页面都是静态的,多年来,Web 设计师依赖于图片、Flash 或者 JavaScript 才能完成修改页面的外观。CSS3 改变了设计师这种思维,借助 CSS3 可以轻松的倾斜、缩放、移动以及翻转元素。
2012 年 9 月,W3C 组织发布了 CSS3 变形工作草案。允许 CSS 把元素变成 2D 或者 3D 空间,这其实就是 CSS3 的 2D 变形和 3D 变形。
CSS3 变形是一些效果的集合,比如平移、旋转、缩放和倾斜效果,每个效果通过变形函数(transform function)来实现。在此之前,要想实现这些效果,必须依赖图片、Flash 或者 JavaScript 才能完成,而现在仅仅使用纯 CSS 就能够实现,大大的提高了开发效率以及页面的执行效率。
变形效果要通过变形函数来实现,语法如下:
transform: none|transform-functions;
那么 CSS3 中为我们提供了哪些变形函数呢?
这里我们整体可以划分出 3 大类:
- 具有 X/Y 的函数:translateX、translateY、sclaeX、scaleY、skewX、skewY
- 2D 变形函数:translate、sclae、rotate、skew、matrix
- 3D 变形函数:rotateX、rotateY、rotate3d、translateZ、translate3d、scaleZ、scale3d、matrix3d
此时,你可能已经做好了逐一击破每个变形函数的思想准备了。
别急,在介绍每个变形函数之前,我们先来了解一下变形相关的属性。
变形属性
transform
transform 属性是 CSS3 中非常重要的一个属性,它允许我们通过 CSS 来控制元素的 2D 或者 3D 转换。语法如下:
transform: none|transform-functions;
取值说明:
- none:不进行任何转换。
- transform-functions:一个或多个转换函数,以空格分隔。
例如:
div {
transform: rotate(45deg);
}
上面的代码中,我们设置了 transform 属性,属性值为 rotate(45deg),表示将元素顺时针旋转 45 度。
transform-origin
transform-origin 属性可以改变元素变形的原点,语法如下:
transform-origin: x-axis y-axis z-axis;
取值说明:
- x-axis:定义变形原点的横坐标,可以是长度值、百分比、left、center、right。
- y-axis:定义变形原点的纵坐标,可以是长度值、百分比、top、center、bottom。
- z-axis:定义变形原点的 z 轴坐标,可以是长度值。
例如:
div {
transform-origin: 50% 50%;
}
上面的代码中,我们设置了 transform-origin 属性,属性值为 50% 50%,表示将元素变形的原点设置在元素的中心位置。
下面我们实战看一下具体的使用方式:
<div></div>
div {
width: 150px;
height: 150px;
margin: 50px;
background-color: blue;
transition: all 1s;
}
div:hover {
transform: rotate(45deg);
}
效果如下:
上面的代码中,我们设置 div 鼠标 hover 的时候进行变形,旋转(transform: rotate(45deg);) 45 度,为了更加平滑,我们加入了 transition 过渡效果。
我们观察整个元素的旋转中心点,是在元素的最中央。
接下来我们可以使用 transform-origin 来修改这个中心点的位置。例如:
div {
width: 150px;
height: 150px;
margin: 50px;
background-color: blue;
transition: all 1s;
transform-origin: left top;
}
效果如下:
在上面的代码中,我们增加了 transform-origin: left top; 这行代码,修改了元素的中心点位置为 left、top,也就是左上角。可以看到因为元素的中心点位置发生了变化,旋转的方式也随之发生了改变。
transform-style
transform-style 属性可以指定元素的子元素是位于 3D 空间还是 2D 平面内,语法如下:
transform-style: flat|preserve-3d;
取值说明:
- flat:所有子元素在 2D 平面内呈现。
- preserve-3d:所有子元素在 3D 空间内呈现。
例如:
div {
transform-style: preserve-3d;
}
上面的代码中,我们设置了 transform-style 属性,属性值为 preserve-3d,表示将元素的子元素在 3D 空间内呈现。
下面我们实战看一下具体的使用方式:
<div class="box">
<div class="up">上</div>
<div class="down">下</div>
<div class="left">左</div>
<div class="right">右</div>
<div class="front">前</div>
<div class="back">后</div>
</div>
.box {
width: 100px;
height: 100px;
border: 1px solid black;
position: relative;
margin: 150px;
transform-style: preserve-3d;
display: flex;
align-items: center;
justify-content: center;
transition: all 1s;
animation: rotate 5s linear infinite;
}
.box>div {
width: 100px;
height: 100px;
position: absolute;
text-align: center;
line-height: 100px;
}
.up {
background-color: red;
transform: translateY(-50px) rotateX(90deg);
}
.down {
background-color: green;
transform: translateY(50px) rotateX(-90deg);
}
.left {
background-color: blue;
transform: translateX(-50px) rotateY(90deg);
}
.right {
background-color: yellow;
transform: translateX(50px) rotateY(-90deg);
}
.front {
background-color: pink;
transform: translateZ(50px);
}
.back {
background-color: orange;
transform: translateZ(-50px);
}
@keyframes rotate {
0% {
transform: rotateY(0deg) rotateX(0deg);
}
100% {
transform: rotateY(360deg) rotateX(360deg);
}
}
效果如下:
在上面的代码中,我们创建了一个立方体,通过 transform-style: preserve-3d; 将子元素在 3D 空间内呈现,然后通过 transform 属性将子元素进行位移和旋转,从而形成了一个立方体。
如果将 transform-style 属性设置为 flat,那么子元素将在 2D 平面内呈现,效果如下:
怎么样?是不是非常直观,一下子就知道 transform-style 属性的作用是什么了。该属性就是指定子元素是在 3D 空间还是 2D 平面中显示。
perspective
perspective 属性可以指定观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定。
简单理解,就是视距,用来设置用户和元素 3D 空间 Z 平面之间的距离。而其效应由他的值来决定,值越小,用户与 3D 空间 Z 平面距离越近,视觉效果更令人印象深刻;反之,值越大,用户与 3D 空间 Z 平面距离越远,视觉效果就很小。
注意当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身。
语法如下:
perspective: none|<length>;
取值说明:
- none:默认值,表示没有透视效果。
- :指定观察者与 z=0 平面的距离,单位可以是 px、em 等。
例如:
.box {
perspective: 500px;
}
上面的代码中,我们设置了 perspective 属性,属性值为 500px,表示观察者与 z=0 平面的距离为 500px。
使用示例
具体例子可参考developer.mozilla.org/zh-CN/docs/…
perspective-origin
perspective-origin 属性可以指定透视效果的原点,即观察者与 z=0 平面之间的连线与视景体近裁剪面的交点。
语法如下:
perspective-origin: [ | | left | center | right ] [ | | top | center | bottom ]?;
取值说明:
- left:观察者与 z=0 平面之间的连线与视景体近裁剪面的交点在元素左边。
- center:观察者与 z=0 平面之间的连线与视景体近裁剪面的交点在元素中间。
- right:观察者与 z=0 平面之间的连线与视景体近裁剪面的交点在元素右边。
- top:观察者与 z=0 平面之间的连线与视景体近裁剪面的交点在元素顶部。
- bottom:观察者与 z=0 平面之间的连线与视景体近裁剪面的交点在元素底部。
例如:
.box {
perspective-origin: 50% 50%;
}
上面的代码中,我们设置了 perspective-origin 属性,属性值为 50% 50%,表示观察者与 z=0 平面之间的连线与视景体近裁剪面的交点在元素中间。
示例
具体例子可参考developer.mozilla.org/zh-CN/docs/…
backface-visibility
backface-visibility 属性可以指定元素背面是否可见。
语法如下:
backface-visibility: visible|hidden;
取值说明:
- visible:默认值,表示元素背面可见。
- hidden:表示元素背面不可见。
例如:
.box {
backface-visibility: hidden;
}
上面的代码中,我们设置了 backface-visibility 属性,属性值为 hidden,表示元素背面不可见。
示例
<div class="container">
<div class="item"></div>
</div>
.container {
margin: 150px;
perspective: 1000px;
}
.item {
width: 100px;
height: 100px;
background-color: red;
backface-visibility: hidden;
animation: rotateAnimation 5s infinite;
}
@keyframes rotateAnimation {
0%{
transform: rotateY(0deg);
}
100%{
transform: rotateY(360deg);
}
}
在上面的代码中,我们在子元素 div.item 上设置了 backface-visibility: hidden,当此元素旋转 180 度到背面时,我们可以发现此时是无法看到背面的。
2D 变形
介绍完 CSS3 中变形的相关属性后,接下来我们就该来看一下具体的变形函数了。
整个 CSS3 为我们提供了相当丰富的变形函数,有 2D 的,有 3D 的。这里我们先来看 2D 的变形函数。
2D 位移
2D 位移对应有 3 个变形函数,分别是 translate、translateX、translateY
用法也非常简单,translate 方法从其当前位置移动元素(根据为 X 轴和 Y 轴指定的参数)。
div { transform: translate(50px, 100px); }
上面的例子把 div 元素从其当前位置向右移动 50 个像素,并向下移动 100 个像素:效果如下:
2D 缩放
2D 缩放对应有 3 个变形函数,分别是 scale、scaleX、scaleY
用法也非常简单,scale 方法用于缩放某个元素的大小。scale 方法需要两个参数,分别代表宽度和高度。如果只指定一个参数,那么宽度与高度相等。
div { transform: scale(2, 4); }
上面的例子把 div 元素的宽度放大为原来的 2 倍,高度放大为原来的 4 倍:效果如下:
2D 旋转
2D 旋转对应有 1 个变形函数,分别是 rotate
用法也非常简单,rotate 方法在二维空间内对元素进行旋转,其语法如下:
div { transform: rotate(45deg); }
上面的例子把 div 元素顺时针旋转 45 度:效果如下:
2D 倾斜
2D 倾斜对应有 3 个变形函数,分别是 skew、skewX、skewY
用法也非常简单,skew 方法用于沿着 X 和 Y 轴对元素进行倾斜变换。skew 方法需要两个参数,分别代表 X 轴和 Y 轴的倾斜角度。如果只指定一个参数,那么 Y 轴的倾斜角度为 0 度。
div { transform: skew(30deg, 20deg); }
上面的例子把 div 元素沿 X 轴倾斜 30 度,沿 Y 轴倾斜 20 度:效果如下:
2D 矩阵
虽然 CSS3 为我们提供了上述的变形函数方便我们进行元素的变形操作,但是毕竟函数个数有限,有些效果是没有提供的,例如镜像翻转的效果。此时就轮到 2D 矩阵函数 matrix 登场了。
matrix 方法通过设置一个包含 6 个值的 2D 变换矩阵 来定义一个 2D 变换。这个方法允许你旋转、缩放、移动以及倾斜元素。
matrix 有六个参数:
matrix(a,b,c,d,e,f)
六个参数对应的矩阵:
这六个参数组成的矩阵与原坐标矩阵相乘计算坐标。计算方式如下:
x 和 y 是元素中每一个像素的初始原点的坐标,而 x' 和 y' 是通过矩阵变化后得到的新原点坐标。
x' = ax+cy+e,表示变换后的水平坐标
y' = bx+dy+f,表示变换后的垂直位置
在 CSS3 中,上面我们所介绍的所有 2D 变形函数都能够通过这个 matrix 矩阵函数来替代。
2D 矩阵 实现 2D 位移
我们首先来看通过矩阵实现偏移效果。
偏移效果前后 x、y 与 x'、y' 所对应的坐标公式为:
x' = x + 偏移量
y' = y + 偏移量
套用上面的公式(x' = ax+cy+e,y' = bx+dy+f)那么各个参数的取值就应该是:
a = 1,c = 0, e = 偏移量
b = 0,d = 1, f = 偏移量
所以换成 matrix 函数就应该是:
matrix(1, 0, 0, 1, x 偏移量, y 偏移量)
下面来做一个测试:
<div></div>
div{
width: 150px;
height: 150px;
background-color: red;
margin: 150px;
transition: all 1s;
}
div:hover{
/* transform: translate(100px, 200px); */
transform: matrix(1, 0, 0, 1, 100, 200);
}
在上面的示例中,使用 translate 和 matrix 两个变形函数的效果一致。
2D 矩阵 实现 2D 缩放
缩放效果前后 x、y 与 x'、y' 所对应的坐标公式为:
x' = x * 缩放比例
y' = y * 缩放比例
套用上面的公式(x' = ax+cy+e,y' = bx+dy+f)那么各个参数的取值就应该是:
a = 缩放比例, c = 0, e = 0
b = 0, d = 缩放比例, f = 0
所以换成 matrix 函数就应该是:
matrix(缩放比例, 0, 0, 缩放比例, 0, 0)
下面来做一个测试:
<div></div>
div{
width: 150px;
height: 150px;
background-color: red;
margin: 150px;
transition: all 1s;
}
div:hover{
/* transform: scale(2, 4); */
transform: matrix(2, 0, 0, 4, 0, 0);
}
在上面的示例中,使用 scale 和 matrix 两个变形函数的效果一致。
2D 矩阵 实现 2D 旋转
旋转效果前后 x、y 与 x'、y' 所对应的坐标公式为:
x' = x * cos(角度) - y * sin(角度)
y' = x * sin(角度) + y * cos(角度)
套用上面的公式(x' = ax+cy+e,y' = bx+dy+f)那么各个参数的取值就应该是:
a = cos(角度), c = -sin(角度), e = 0
b = sin(角度), d = cos(角度), f = 0
所以换成 matrix 函数就应该是:
matrix(cos(角度), sin(角度), -sin(角度), cos(角度), 0, 0)
下面来做一个测试:
<div></div>
div{
width: 150px;
height: 150px;
background-color: red;
margin: 150px;
transition: all 1s;
}
div:hover{
/* transform: rotate(45deg); */
transform: matrix(0.707, 0.707, -0.707, 0.707, 0, 0);
}
在上面的示例中,使用 rotate 和 matrix 两个变形函数的效果一致。
2D 矩阵 实现 2D 倾斜
倾斜效果前后 x、y 与 x'、y' 所对应的坐标公式为:
x' = x * tan(角度)
y' = y * tan(角度)
套用上面的公式(x' = ax+cy+e,y' = bx+dy+f)那么各个参数的取值就应该是:
a = 1, c = tan(角度), e = 0
b = tan(角度), d = 1, f = 0
所以换成 matrix 函数就应该是:
matrix(1, tan(角度), tan(角度), 1, 0, 0)
下面来做一个测试:
<div></div>
div{
width: 150px;
height: 150px;
background-color: red;
margin: 150px;
transition: all 1s;
}
div:hover{
/* transform: skew(30deg, 20deg); */
transform: matrix(1, 0.577, 0.577, 1, 0, 0);
}
在上面的示例中,使用 skew 和 matrix 两个变形函数的效果一致。
2D 矩阵 实现 水平镜像
镜像效果前后 x、y 与 x'、y' 所对应的坐标公式为:
x' = x * -1
y' = y * 1
套用上面的公式(x' = ax+cy+e,y' = bx+dy+f)那么各个参数的取值就应该是:
a = -1, c = 0, e = 0
b = 0, d = 1, f = 0
所以换成 matrix 函数就应该是:
matrix(-1, 0, 0, 1, 0, 0)
下面来做一个测试:
<div class="container">
<div class="item left"></div>
<div class="item right"></div>
</div>
.container {
width: 150px;
height: 150px;
margin: 150px;
transition: all 1s;
display: flex;
}
.container:hover {
transform: matrix(-1, 0, 0, 1, 0, 0);
}
.item {
flex: 1;
}
.left {
background-color: red;
}
.right {
background-color: green;
}
效果如下:
3D 变形
使用二维变形能够改变元素在水平和垂直轴线,然而还有一个轴沿着它,可以改变元素。使用三维变形,可以改变元素在 Z 轴位置。
3D 坐标系
三维变换使用基于二维变换的相同属性,如果熟悉二维变换就会发现,3D 变形的功能和 2D 变换的功能类似。CSS3 中的 3D 变换只要包含以下几类:
- 3D 位移:包括 translateZ 和 translate3d 两个变形函数。
- 3D 旋转:包括 rotateX、rotateY、rotateZ 和 rotate3d 这四个变形函数。
- 3D 缩放:包括 scaleZ 和 sclae3d 两个变形函数。
- 3D 矩阵:和 2D 变形一样,也有一个 3D 矩阵功能函数 matrix3d
3D 位移
translate3d() CSS 函数在 3D 空间内移动一个元素的位置。这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离。
transform: translate3d(tx, ty, tz);
- tx:在 X 轴的位移距离。
- ty:在 Y 轴的位移距离。
- tz:在 Z 轴的位移距离。值越大,元素离观察者越近,值越小,元素离观察者越远
例如:
<div class="container">
<div class="item"></div>
</div>
.container {
width: 150px;
height: 150px;
margin: 150px;
transition: all 1s;
display: flex;
perspective: 1000px;
}
.item {
flex: 1;
background-color: red;
transition: all 2s;
}
.item:hover {
transform: translate3d(200px, 100px, 500px);
}
在上面的代码中,我们设置 div.item 被 hover 的时候进行 3D 位移,也就是 X、Y、Z 轴同时进行移动。注意这里要设置父元素的透视效果,也就是设置 perspective 值,否则看不出 Z 轴的移动效果。效果如下:
3D 旋转
rotate3d() CSS 函数在 3D 空间中旋转一个元素。这个旋转由一个四元数表示,分别表示他在三个方向上旋转的角度。
transform: rotate3d(x, y, z, angle);
- x:表示旋转轴的 X 轴坐标,可以是 0 到 1 之间的数值。
- y:表示旋转轴的 Y 轴坐标,可以是 0 到 1 之间的数值。
- z:表示旋转轴的 Z 轴坐标,可以是 0 到 1 之间的数值。
- angle:表示旋转的角度,正值表示顺时针旋转,负值表示逆时针旋转。
例如:
<div class="container">
<div class="item"></div>
</div>
.container {
width: 150px;
height: 150px;
margin: 150px;
transition: all 1s;
display: flex;
perspective: 1000px;
}
.item {
flex: 1;
background-color: red;
transition: all 2s;
}
.item:hover {
transform: rotate3d(1, 1, 0, 45deg);
}
在上面的代码中,我们设置 div.item 被 hover 的时候进行 3D 旋转,也就是 X、Y、Z 轴同时进行旋转。效果如下:
3D 缩放
scale3d() CSS 函数在 3D 空间中缩放一个元素的大小。这个缩放由一个三维向量表示,分别表示他在三个方向上缩放的比例。
transform: scale3d(sx, sy, sz);
- sx:表示在 X 轴方向的缩放比例。
- sy:表示在 Y 轴方向的缩放比例。
- sz:表示在 Z 轴方向的缩放比例。
但是 scaleX 和 scaleY 变形效果很明显,但是 scaleZ 却基本看不出有什么效果。原因很简单,scaleZ 是 Z 轴上面的缩放,也就是厚度上面的变化,所以如果不是立方体结构,基本上是看不出来 Z 轴上面的缩放效果的。
一般来讲,我们不会将 scaleZ 和 scale3d 单独使用,因为 scaleZ 和 scale3d 这两个变形函数在单独使用时没有任何效果,需要配合其他的变形函数一起使用时才会有效果。
我么使用立方体进行举例
例如:
<div class="box">
<div class="up">上</div>
<div class="down">下</div>
<div class="left">左</div>
<div class="right">右</div>
<div class="front">前</div>
<div class="back">后</div>
</div>
.box {
width: 100px;
height: 100px;
border: 1px solid black;
position: relative;
margin: 150px;
transform-style: preserve-3d;
display: flex;
align-items: center;
justify-content: center;
transition: all 1s;
transform: rotateY(45deg) rotateX(45deg);
}
.box:hover {
transform: rotateY(45deg) rotateX(45deg) scaleZ(0.5);
}
.box>div {
width: 100px;
height: 100px;
position: absolute;
text-align: center;
line-height: 100px;
}
.up {
background-color: red;
transform: translateY(-50px) rotateX(90deg);
}
.down {
background-color: green;
transform: translateY(50px) rotateX(-90deg);
}
.left {
background-color: blue;
transform: translateX(-50px) rotateY(90deg);
}
.right {
background-color: yellow;
transform: translateX(50px) rotateY(-90deg);
}
.front {
background-color: pink;
transform: translateZ(50px);
}
.back {
background-color: orange;
transform: translateZ(-50px);
}
效果如下:
3D 矩阵
CSS3 中的 3D 矩阵比 2D 矩阵复杂,从二维到三维,在矩阵里 33 变成 44,即 9 到 16。
对于 3D 矩阵而言,本质上很多东西与 2D 是一致的,只是复杂程度不一样而已。
其矩阵如下:
transform: matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
这里举几个 3D 矩阵的例子:
translate3d(tx,ty,tz) 等价于 matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,tx,ty,tz,1)
scale3d(sx,sy,sz) 等价于 matrix3d(sx,0,0,0,0,sy,0,0,0,0,sz,0,0,0,0,1)
rotate3d(x,y,z,a) 这个涉及到数学知识,第四个参数 alpha 用于 sc 和 sq 中
当然除非是开发库函数,否则我严重怀疑是否会有人放着 rotate3d 不用,偏要去挑战用 matrix3d 模拟 rotate3d。
总结
请简述一下 CSS3 中新增的变形如何使用?
在 CSS3 中的变形分为 2D 变形和 3D 变形。
整体可以划分出 3 大类:
- 具有 X/Y 的函数:translateX、translateY、sclaeX、scaleY、skewX、skewY
- 2D 变形函数:translate、sclae、rotate、skew、matrix
- 3D 变形函数:rotateX、rotateY、rotate3d、translateZ、translate3d、scaleZ、scale3d、matrix3d
另外,还有一些重要的变形属性,例如:
- transform 属性
- transform-origin 属性
- transform-style 属性
- perspective 属性
- perspective-origin 属性
- backface-visibility 属性