转换是 CSS3 中具有颠覆性的一个特征,可以实现元素的位移、旋转、变形、缩放。
通过 transform 转换来实现 2D 转换或者 3D 转换。
2D 转换包括:
设置元素的缩放效果,只要给元素添加上了这个属性就能控制它放大还是缩小。
语法:
transform: scale(x, y);
transform: scale(2, 0.5);
参数:
x:表示水平方向的缩放倍数
y:表示垂直方向的缩放倍数
注意:
注意其中的 x 和 y 用逗号分割
如果只写一个值就是等比例缩放
不会影响到其他元素
取值:
<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>
2D 移动是 2D 转换里面的一种功能,可以改变元素在页面中的位置,类似定位。
语法:
transform: translate(x, y);
transform: translateX(n);
transform: translateY(n);
注意:
综合写法,如果只写一个值,则表示水平移动
translate 最大的优点:不会影响到其他元素的位置
translate 中的百分比单位是相对于自身元素的
对行内标签没有效果
注意:与相对定位相比,效果是一样的,但是相对定位会影响子元素的定位参考。
使用:让绝对定位中的盒子在父元素里居中,我们知道,如果想让一个标准流中的盒子在父盒子里居中(水平方向看),可以将其设置 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>
2D 旋转指的是让元素在 2 维平面内顺时针旋转或者逆时针旋转。
语法:
transform: rotate(角度);
transform: rotate(45deg);
注意:
用法:
<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 旋转时,默认是以盒子的正中心为坐标原点的。
如果想改变 2D 转换的中心点,可以用 transform-origin 属性,可以设置元素转换的中心点。
取值:
语法:
transform-origin: 水平坐标 垂直坐标;
transform-origin: 50px 50px;
transform-origin: center bottom;
注意后面的参数 x 和 y 用空格隔开
x y 默认转换的中心点是元素的中心点(50% 50%)
实现扑克牌效果
<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>
设置元素的倾斜
语法:
transform: skew(水平倾斜角度,垂直倾斜角度);
transform: skew(45deg,10deg);
参数:
<style>
.skew {
width: 100px;
height: 100px;
background: #000fff;
}
.skew:hover {
transform: skew(45deg, 10deg);
}
style>
<div class="skew">div>
注意:
照片就是 3D 物体在2D平面呈现的例子。
3D转换的特点:
三维坐标系
3D呈现:transform-style,控制子元素是否开启三维立体环境
元素沿着 X 轴缩放
语法:
transform: scaleX(x);
transform: scaleX(1.2);
参数:
取值:
<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>
元素沿着 Y 轴缩放
语法:
transform: scaleY(y);
transform: scaleY(1.2);
参数:
取值:
<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>
元素沿着 Z 轴缩放
语法:
transform: scaleZ(z);
transform: scaleZ(1.2);
参数:
取值:
<style>
.box {
width: 100px;
height: 100px;
margin: 100px auto;
background: #ddd;
perspective: 800px;
}
.box>.fill {
height: 100px;
background: #03A9F4;
opacity: .5;
transition: 0.3s;
}
.scaleZ:hover .fill {
transform: scaleZ(2);
}
style>
<div class="box scaleZ">
<div class="fill">div>
div>
设置元素的 3D 缩放效果
语法:
transform: scale3d(x,y,z);
transform: scale3d(2,2,2);
参数:
取值:
<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>
3D 移动在 2D 移动的基础上多加了一个可以移动的方向,就是 z 轴方向。
元素沿着 X 轴移动
语法:
transform: translateX(x);
transform: translateX(100px);
参数:
取值:
<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>
元素沿着 Y 轴移动
语法:
transform: translateY(y);
transform: translateY(100px);
参数:
取值:
<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>
元素沿着 Z 轴移动
语法:
transform: translateZ(z);
transform: translateZ(100px);
参数:
取值:
<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 的效果的。
元素进行 3D 移动
语法:
transform: translate3d(x,y,z);
transform: translate3d(100px,100px,100px);
参数:
取值:
<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>
3D 旋转:3D 旋转指可以让元素在三维平面内沿着 x 轴,y 轴,z 轴或者自定义轴进行旋转。
旋转的方向:(左手法则)左手握住旋转轴,竖起拇指指向旋转轴的正方向,正向就是其余手指卷曲的方向。
注意:所有的 3D 旋转,对着正方向去看,都是顺时针旋转。
元素沿着 X 轴旋转
语法:
transform: rotateX(a);
transform: rotateX(360deg);
参数:
取值:
<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,方能生效。我们在后面会讲解透视属性。
元素沿着 Y 轴旋转
语法:
transform: rotateY(a);
transform: rotateY(360deg);
参数:
取值:
<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>
元素沿着 Z 轴旋转
语法:
transform: rotateZ(a);
transform: rotateZ(360deg);
参数:
取值:
<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>
沿着自定义轴,元素 3D 旋转,综合写法
语法:
transform: rotate3d(1, 1, 1, 0);
transform: rotate3d(x, y, 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>
元素隐藏背面内容:backface-visibility: hidden;
<style>
.box {
width: 300px;
height: 300px;
margin: 50px auto;
position: relative;
transition: all 2s;
/* 子元素保留 3D 效果 */
/* transform-style: preserve-3d; */
}
.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);
} */
/* .box:hover {
transform: rotateY(180deg);
} */
style>
<div class="box">
<div class="box-item box1">div>
<div class="box-item box2">div>
div>
显示屏是一个 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>
透视图片效果:
<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>
关于透视三个问题:
第一个问题:translateZ 的值越大,是否图片越大?
比如之前学到的属性值:transform: translateZ(400px); 增加 Z 轴的距离,那么 Z 轴越大,是不是也就代表着,这个元素,离我们的距离越近?
那么,你把一张图片,贴到你脸上,有什么效果? 是不是非常大?这个 perspective 配合 transform:translateZ 就有这种效果。
这个其实很像我们现实中的例子一样,一张远处的图片,慢慢的移动到你脸上, 你会看见图片越来越大,贴到你脸上的时候,是不是你就看不见了?
到 800px 的时候,你人都和图片融合在一体了, 如果 801px 是不是你都穿过这张图片了?道理是一样的。
第二个问题:translateZ 的值为负值,增加 perspective 图片是否会变小?
把 translateZ 设置成负值(按照我们的想法,Z 的值是正数,说明这个图片,离我们越近,那么反之,负值,离我们越远),修改 perspective 的值,把他的值变小(按正常来说,值越小,是不是就代表我们离屏幕越近, 看的东西也就越大)。
结果是 perspective 值越小,图片越小,怎么图片不是越来越大呢? 我们离屏幕越近,图片应该越大才对啊,怎么变小了呢?
第三个问题:translateZ 为 0,调整 perspective 图片是否会变大变小?
按正常来说 perspective 值越小,是不是我们就离屏幕越近,那么图片也会越大(translateZ 是移动图片,perspective 是移动人和屏幕的距离,那么把 translateZ 归零,然后调整 perspective。)
结果是 perspective 好像无论是增加,还是减少,图片都没有任何变化。
为什么会出现这种问题呢?
实际情况是,我们看到的,并不是图片本身,而是图片的投影,投影是什么鬼,下面我们详细看。
我们下面分析总结一下各种情况:
第一个情况,translateZ 的值越大,图片越大。
translateZ 的值越大,代表图片越远离屏幕,那么相对于屏幕上的投影也就越大。
第二个情况,translateZ 的值越小,图片越小。
translateZ 的值越小,也就是负值的情况,图片会跑出屏幕,那么屏幕上的图片的倒影,也就越小。
第三个情况,translateZ 为 0 的时候,调整 perspective 的值,图片的大小没有改变
translateZ 为 0 的时候,图片不会移动,也就不会有投影了。
第四个情况,为什么 translateZ 为负数之后,减少 perspective 的值后,图片不是变大, 反而变小呢?
translateZ 为负数之后,人眼离得越近看的倒影越小。
注意:
perspective 属性需要加在父元素上
perspective-origin 透视点,这个属性也是设置在父级身上
使用 2D 位移实现上下左右居中。
使用 2D 缩放实现 hover 放大效果。
使用 2D 旋转实现扑克牌效果。
使用 3D 转换实现翻转的照片。
使用 3D 转换实现立方体。
,那么图片也会越大(translateZ 是移动图片,perspective 是移动人和屏幕的距离,那么把 translateZ 归零,然后调整 perspective。)
结果是 perspective 好像无论是增加,还是减少,图片都没有任何变化。
为什么会出现这种问题呢?
实际情况是,我们看到的,并不是图片本身,而是图片的投影,投影是什么鬼,下面我们详细看。
我们下面分析总结一下各种情况:
第一个情况,translateZ 的值越大,图片越大。
translateZ 的值越大,代表图片越远离屏幕,那么相对于屏幕上的投影也就越大。
第二个情况,translateZ 的值越小,图片越小。
translateZ 的值越小,也就是负值的情况,图片会跑出屏幕,那么屏幕上的图片的倒影,也就越小。
第三个情况,translateZ 为 0 的时候,调整 perspective 的值,图片的大小没有改变
translateZ 为 0 的时候,图片不会移动,也就不会有投影了。
第四个情况,为什么 translateZ 为负数之后,减少 perspective 的值后,图片不是变大, 反而变小呢?
translateZ 为负数之后,人眼离得越近看的倒影越小。
注意:
perspective 属性需要加在父元素上
perspective-origin 透视点,这个属性也是设置在父级身上
使用 2D 位移实现上下左右居中。
使用 2D 缩放实现 hover 放大效果。
使用 2D 旋转实现扑克牌效果。
使用 3D 转换实现翻转的照片。
使用 3D 转换实现立方体。