1 2D转换
转换是 CSS3 中具有颠覆性的⼀个特征,可以实现元素的位移、旋转、变形、缩放。
通过 transform 转换来实现 2D 转换或者 3D 转换。
2D转换包括:
-
缩放
-
移动
-
旋转
-
倾斜
1.1 scale
设置元素的缩放效果
语法:
-
transform: scale(x, y);
-
transform: scale(2, 0.5);
参数:
-
x:表示水平方向的缩放倍数
-
y:表示垂直方向的缩放倍数
注意:如果只写⼀个值就是等比例缩放
取值:
-
⼤于1表示放⼤
-
⼩于1表示缩⼩
-
不能为百分⽐
给元素设置 2D 转换,并不会把兄弟元素挤⾛
<style> .box { float: left; width: 200px; height: 200px; } .box1 { transform: scale(1.2); background: #ff0000; } .box2 { background: #00ff00; } </style> <div class="box box1"></div> <div class="box box2"></div>
1.2 translate
设置元素的移动效果
语法:
-
transform: translate(⽔平位移, 垂直位移);
-
transform: translate(-50%, -50%);
参数:
-
参数为百分⽐,相对于⾃身移动
-
正值:向右和向下
-
负值:向左和向上
-
如果只写⼀个值,则表示⽔平移动
注意:与相对定位相⽐,效果是⼀样的,但是相对定位会影响⼦元素的定位参考。
使用:让绝对定位中的盒⼦在父元素里居中,我们知道,如果想让⼀个标准流中的盒⼦在⽗盒⼦⾥居中(⽔平⽅向看),可以将其设置margin: 0 auto; 属性。
如果盒⼦是绝对定位的,如果还想让其居中(位于⽗盒⼦的正中间),之前的做法是利用 margin 负值
<style> .wrapper { float: left; width: 600px; height: 600px; background: #0000ff; position: relative; } .box { float: left; width: 200px; height: 200px; } .box1 { background: #ff0000; margin: -100px 0 0 -100px; position: absolute; left: 50%; top: 50%; z-index: 9; } </style> <div class="wrapper"> <div class="box box1"></div> </div>
现在,我们还可以利⽤ translate 偏移来做,这也是⽐较推荐的写法
<style> .wrapper { float: left; width: 600px; height: 600px; background: #0000ff; position: relative; } .box { float: left; width: 200px; height: 200px; } .box1 { background: #ff0000; transform: translate(-50%, -50%); position: absolute; left: 50%; top: 50%; z-index: 9; } </style> <div class="wrapper"> <div class="box box1"></div> </div>
1.3 rotate
设置元素的旋转
语法:
-
transform: rotate(⻆度);
-
transform: rotate(45deg);
参数:
-
单位是deg
-
正值:顺时针旋转
-
负值:逆时针旋转
<style> .rotate { width: 100px; height: 100px; background: #000fff; } .rotate:hover { transform: rotate(45deg); } </style> <div class="rotate"></div>
transform 可以书写多个 2D 转换,中间⽤空格隔开。我们可以将 transform 的两个属性合并起来写
<style> .rotate { width: 100px; height: 100px; } .rotate1 { background: #000fff; } .rotate2 { background: #00ff00; } .rotate1:hover { transform: translate(200px) rotate(45deg); } .rotate2:hover { transform: rotate(45deg) translate(200px); } </style> <div class="rotate rotate1"></div> <div class="rotate rotate2"></div>
但是这两者效果不同,第⼀种是先平移再旋转,第⼆种是先旋转再平移。
rotate 旋转时,默认是以盒⼦的正中⼼为坐标原点的。如果想改变旋转的坐标原点,可以⽤ transform-origin 属性
取值:
-
px
-
百分⽐
-
英⽂单词(left、center等)
语法:
-
transform-origin: ⽔平坐标 垂直坐标;
-
transform-origin: 50px 50px;
-
transform-origin: center bottom;
实现扑克牌效果
<style> .box { width: 300px; height: 440px; margin: 100px auto; position: relative; } .item { width: 100%; height: 100%; border: 1px solid #fff000; position: absolute; left: 0; top: 0; /* 变换中心原点 */ transform-origin: center bottom; } .box:hover .item:nth-child(6) { transform: rotate(-10deg); } .box:hover .item:nth-child(5) { transform: rotate(-20deg); } .box:hover .item:nth-child(4) { transform: rotate(-30deg); } .box:hover .item:nth-child(3) { transform: rotate(-40deg); } .box:hover .item:nth-child(2) { transform: rotate(-50deg); } .box:hover .item:nth-child(1) { transform: rotate(-60deg); } .box:hover .item:nth-child(8) { transform: rotate(10deg); } .box:hover .item:nth-child(9) { transform: rotate(20deg); } .box:hover .item:nth-child(10) { transform: rotate(30deg); } .box:hover .item:nth-child(11) { transform: rotate(40deg); } .box:hover .item:nth-child(12) { transform: rotate(50deg); } .box:hover .item:nth-child(13) { transform: rotate(60deg); } </style> <div class="box"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
实现红心效果
<style> .heart { position: relative; width: 100px; height: 100px; margin-top: 80px; } .heart:before, .heart:after { position: absolute; content: ""; left: 50px; top: 0; width: 50px; height: 80px; background: red; border-radius: 50px 50px 0 0; transform: rotate(-45deg); transform-origin: 0 100%; } .heart:after { left: 0; transform: rotate(45deg); transform-origin: 100% 100%; } .heart:hover { transform: scale(1.2); } </style> <div class="heart"></div>
1.4 skew
设置元素的倾斜
语法:
-
transform: skew(⽔平倾斜⻆度,垂直倾斜⻆度);
-
transform: skew(45deg,10deg);
参数:
-
单位是deg
-
正值:顺时针倾斜
-
负值:逆时针倾斜
<style> .skew { width: 100px; height: 100px; background: #000fff; } .skew:hover { transform: skew(45deg, 10deg); } </style> <div class="skew"></div>
注意:
-
转换操作不会影响到其他元素
-
只能添加给块元素或行内块元素,不能添加给⾏内元素
-
复合写法:可以同时添加多个变形操作,先执⾏前⾯的,再执⾏后⾯的
2 3D转换
2.1 缩放
2.1.1 scaleX
元素沿着 X 轴缩放
语法:
-
transform: scaleX(x);
-
transform: scaleX(1.2);
参数:
-
x:表示水平方向的缩放倍数
取值:
-
⼤于1表示放⼤
-
⼩于1表示缩⼩
-
不能为百分⽐
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .scaleX:hover .fill { transform: scaleX(2); } </style> <div class="box scaleX"> <div class="fill"></div> </div>
2.1.2 scaleY
元素沿着 Y 轴缩放
语法:
-
transform: scaleY(y);
-
transform: scaleY(1.2);
参数:
-
y:表示垂直方向的缩放倍数
取值:
-
⼤于1表示放⼤
-
⼩于1表示缩⼩
-
不能为百分⽐
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .scaleY:hover .fill { transform: scaleY(2); } </style> <div class="box scaleY"> <div class="fill"></div> </div>
2.1.3 scaleZ
元素沿着 Z 轴缩放
语法:
-
transform: scaleZ(z);
-
transform: scaleZ(1.2);
参数:
-
z:表示面向屏幕方向的缩放倍数
取值:
-
⼤于1表示放⼤
-
⼩于1表示缩⼩
-
不能为百分⽐
2.1.4 scale3d
设置元素的 3D 缩放效果
语法:
-
transform: scale3d(x,y,z);
-
transform: scale3d(2,2,2);
参数:
-
x:表示水平方向的缩放倍数
-
y:表示垂直方向的缩放倍数
-
z:表示面向屏幕方向的缩放倍数
取值:
-
⼤于1表示放⼤
-
⼩于1表示缩⼩
-
不能为百分⽐
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; perspective: 800px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .scale3d:hover .fill { transform: scale3d(2, 2, 1); } </style> <div class="box scale3d"> <div class="fill"></div> </div>
2.2 移动
2.2.1 translateX
元素沿着 X 轴移动
语法:
-
transform: translateX(x);
-
transform: translateX(100px);
参数:
-
x:表示水平方向的移动
取值:
-
正值:向右
-
负值:向左
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; perspective: 800px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .translateX:hover .fill { transform: translateX(50px); } </style> <div class="box translateX"> <div class="fill"></div> </div>
2.2.2 translateY
元素沿着 Y 轴移动
语法:
-
transform: translateY(y);
-
transform: translateY(100px);
参数:
-
y:表示垂直方向的移动
取值:
-
正值:向下
-
负值:向上
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; perspective: 800px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .translateY:hover .fill { transform: translateY(50px); } </style> <div class="box translateY"> <div class="fill"></div> </div>
2.2.3 translateZ
元素沿着 Z 轴移动
语法:
-
transform: translateZ(z);
-
transform: translateZ(100px);
参数:
-
z:表示面向屏幕方向的移动
取值:
-
正值:向前
-
负值:向后
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; /* ⽗元素加透视效果 */ perspective: 800px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .translateZ:hover .fill { transform: translateZ(200px); } </style> <div class="box translateZ"> <div class="fill"></div> </div>
如果不加透视属性,是看不到 translateZ 的效果的。
2.2.4 translate3d
元素进行 3D 移动
语法:
-
transform: translate3d(x,y,z);
-
transform: translate3d(100px,100px,100px);
参数:
-
x:表示水平方向的移动
-
y:表示垂直方向的移动
-
z:表示面向屏幕方向的移动
取值:
-
正值:向右、向下、向前
-
负值:向左、向上、向后
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; /* ⽗元素加透视效果 */ perspective: 800px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .translate3d:hover .fill { transform: translate3d(50px, 50px, 200px); } </style> <div class="box translate3d"> <div class="fill"></div> </div>
2.3 旋转
旋转的方向:(左⼿法则)左⼿握住旋转轴,竖起拇指指向旋转轴的正⽅向,正向就是其余⼿指卷曲的⽅向。
注意:所有的3d旋转,对着正⽅向去看,都是顺时针旋转。
2.3.1 rotateX
元素沿着 X 轴旋转
语法:
-
transform: rotateX(a);
-
transform: rotateX(360deg);
参数:
-
a:角度,单位为deg
取值:
-
正值:顺时针旋转
-
负值:逆时针旋转
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; /* ⽗元素加透视效果 */ perspective: 200px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .rotateX:hover .fill { transform: rotateX(45deg); } </style> <div class="box rotateX"> <div class="fill"></div> </div>
透视的是要加给图⽚的⽗元素 div,⽅能⽣效。我们在后⾯会讲解透视属性。
2.3.2 rotateY
元素沿着 Y 轴旋转
语法:
-
transform: rotateY(a);
-
transform: rotateY(360deg);
参数:
-
a:角度,单位为deg
取值:
-
正值:顺时针旋转
-
负值:逆时针旋转
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; /* ⽗元素加透视效果 */ perspective: 200px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .rotateY:hover .fill { transform: rotateY(45deg); } </style> <div class="box rotateY"> <div class="fill"></div> </div>
2.3.3 rotateZ
元素沿着 Z 轴旋转
语法:
-
transform: rotateZ(a);
-
transform: rotateZ(360deg);
参数:
-
a:角度,单位为deg
取值:
-
正值:顺时针旋转
-
负值:逆时针旋转
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; /* ⽗元素加透视效果 */ perspective: 200px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .rotateZ:hover .fill { transform: rotateZ(45deg); } </style> <div class="box rotateZ"> <div class="fill"></div> </div>
2.3.4 rotate3d
沿着自定义轴,元素 3D 旋转,综合写法
语法:
-
transform: rotate3d(1, 1, 1, 0);
-
transform: rotate3d(x, y, z, a)
取值:
-
x 表示旋转轴X坐标方向的矢量。
-
y 表示旋转轴Y坐标方向的矢量。
-
z 表示旋转轴Z坐标方向的矢量。
-
a 表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。
<style> .box { width: 100px; height: 100px; margin: 100px auto; background: #ddd; /* ⽗元素加透视效果 */ perspective: 200px; } .box>.fill { height: 100px; background: #03A9F4; opacity: .5; transition: 0.3s; } .rotate3d1 .fill { transform: rotate3d(1, 1, 0, 45deg); } .rotate3d2 .fill { transform: rotate3d(-1, 1, 0, 45deg); } </style> <div class="box rotate3d1"> <div class="fill"></div> </div> <div class="box rotate3d2"> <div class="fill"></div> </div>
2.3.5 3D旋转
<style> .box { width: 300px; height: 300px; margin: 50px auto; position: relative; } .box-item { width: 100%; height: 100%; position: absolute; border-radius: 50%; transition: all 2s; /* 隐藏背面 */ backface-visibility: hidden; } .box1 { background: #ff0000 } .box2 { background: #0000ff; transform: rotateY(180deg); } .box:hover .box1 { transform: rotateY(180deg); } .box:hover .box2 { transform: rotateY(0deg); } </style> <div class="box"> <div class="box-item box1"></div> <div class="box-item box2"></div> </div>
2.4 透视
显示屏是⼀个 2D 平⾯,图像之所以具有⽴体感(3D效果),其实只是⼀种视觉呈现,通过透视可以 实现此⽬的。
透视可以将⼀个2D平⾯,在转换的过程当中,呈现3D效果。但仅仅只是视觉呈现出3d 效果,并不是正真 的3d。
简单来说,就是设置这个属性后,那么就可以模拟出像我们人看电脑上的显示的元素一样。比如说,perspective:800px; 意思就是,我在离屏幕 800px 的地方观看这个元素。(这个属性,要设置在父元素上面)
加了perspective 和 没有加是什么区别, 第一个小方块,是有加的效果,能明显的看到空间感了有没有, 感觉他是真的像在旋转, 而第二个呢,像是在伸缩。
<style> .wrapper1 { /* 透视:加给变换的⽗盒⼦ */ /* 设置的是⽤户的眼睛距离 平⾯的距离 */ /* 透视效果只是视觉上的呈现,并不是正真的3d */ perspective: 400px; } .box { width: 300px; height: 220px; margin: 100px auto 0; background: #ff0000; transition: all 2s; } .box:hover { transform: rotateY(180deg); } </style> <div class="wrapper1"> <div class="box"></div> </div> <div class="wrapper2"> <div class="box"></div> </div>
比如之前学到的属性值:transform: translateZ(400px); 增加 Z 轴的距离,那么 Z 轴越大,是不是也就代表着,这个元素,离我们的距离越近?
那么,你把一张图片,贴到你脸上,有什么效果? 是不是非常大?这个 perspective 配合 transform:translateZ 就有这种效果。
<style> .wrapper { /* ⽗元素加透视效果 */ perspective: 800px; } .box { width: 200px; margin: 200px auto; background: #ff0000; transform: translateZ(400px) } .box::after { content: ''; display: block; clear: both; } .box>img { float: left; width: 100%; } .box:hover { /* translateZ 必须配合透视来使⽤ */ /* transform: translateZ(400px) */ } </style> <div class="wrapper"> <div class="box"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F0719%2Fa38e408fp00qwhqu10032d000go00b4p.png&thumbnail=650x2147483647&quality=80&type=jpg" alt=""></div> </div>
这个其实很像我们现实中的例子一样,一张远处的图片,慢慢的移动到你脸上, 你会看见图片越来越大,贴到你脸上的时候,是不是你就看不见了?
到 800px 的时候,你人都和图片融合在一体了, 如果 801px 是不是你都穿过这张图片了?道理是一样的。
那么 transform:translateZ,到负数的时候,是不是值越小,图片离我们越远,同理的图片也就越小呢?
按照我们的思路继续,如果 perspective 值越小,是不是我们就离屏幕越近,那么图片也会越大(translateZ 是移动图片,perspective 是移动人和屏幕的距离,对吧,那么把 translateZ 归零。然后增加 perspective 试试看。)
然后,你会惊奇的发现,好像无论是增加,还是减少,图片都没有任何变化。
把 translateZ 设置成负值(按照我们的想法,Z 的值是正数,说明这个图片,离我们越近,那么反之,负值,离我们越远)移动 perspective 的值,把他的值变小(正常来说,值越小,是不是就代表我们离屏幕越近, 看的东西也就越大)
然后,你又会惊奇的发现,怎么图片不是越来越大呢? 我们离屏幕越近,图片应该越大才对啊,怎么变小了呢?
实际情况是,我们看到的,并不是图片本身,而是图片的投影。是不是有点晕了,投影是什么鬼。
我们下面分析总结一下各种情况:
第一个情况,translateZ 的值越大,图片越大。
第二个情况,translateZ 的值越小,图片越小。
第三个情况,translateZ 为 0 的时候,图片不会移动,也就不会有投影了。
第四个情况,translateZ 为负数之后,人眼离得越近看的倒影越小。
最后补充一点,这个perspective 属性呢,要放在父级身上。
还有一个属性 perspective-origin,这个属性也是设置在父级身上。
这个属性呢,默认值是 center center,也就是 居中。这两个参数呢,是根据自身来定位的, 0px 0px 代表着元素的左上角,center center代表着元素的中间点。可以设置像素 50px 也可设置百分比 50%,还可以设置 top right left bottom center 等。
这个属性有什么用呢? 这个属性是相当于人 的眼睛看哪里。你没有设置,也就是默认看父元素中间的地方。