空间 是从坐标轴角度定义的,x、y、z 三条坐标轴构成了一个立体空间,z 轴位置与视线方向相同
空间转换也叫 3D 转换,同样用 transform
表示
空间位移
使用 translate
实现元素空间位移效果,取值 正负 均可,可以是像素单位值,也可以是百分比,语法如下:
- transform: translate3d(x, y, z);
- transform: translateX(值);
- transform: translateY(值);
- transform: translateZ(值);
HTML
<style>
div {
margin: 0 auto;
width: 100px;
height: 100px;
background-color: red;
}
div:hover {
transform: translate3d(20px, 50px, 60px);
/* transform: translateX(20px); */
/* transform: translateY(50px); */
/* transform: translateZ(60px); */
}
</style>
<body>
<div class="box"></div>
</body>
透视
同一个物体,在视觉上,近处的清楚,远处的模糊,透视原理与此类似
默认情况下,无法观察到 Z 轴的位移效果,因为 Z 轴是视线方向。移动效果应该是 距离的远或近 ,由于电脑是平面的,默认无法观察到远近效果,
基于上述情况,可以使用 perspective
属性,在空间转换时,为元素 父级 添加 近大远小、近实远虚 的 视觉效果 。
perspective
属性的取值是像素单位数值,范围一般在 800 - 1200 之间,如果数值太大,透视效果不太明显;数值太小,透视效果又太明显了,所以一般在 800 - 1200px 之间最合适。
透视距离也称为 视距 ,所谓的视距就是人的眼睛到电脑屏幕的距离
空间旋转
使用 rotate
实现元素空间旋转效果,语法:
- transform: rotateX();
- transform: rotateY();
- transform: rotateZ();
HTML
<style>
body {
perspective: 1000px;
}
div {
margin: 0 auto;
width: 100px;
height: 100px;
background-color: red;
transition: all 1s;
}
div:hover {
transform: rotateY(-60deg);
}
</style>
<body>
<div class="box"></div>
</body>
判断旋转方向用左手法则 :左手握住旋转轴, 拇指指向正值方向,手指弯曲方向为旋转正值方向
例如:上例中是沿着 Y 轴负方向旋转 60° ,视觉效果是:Y 轴是竖直方向,根据左手法则,拇指指向的方向为正,所以图形应该向左旋转,即向里旋转 60°
沿着 X 轴旋转 -60°,根据左手法则,手指弯曲方向为旋转正值方向,在视觉上是向里旋转为正方向,由于是负方向,所以它会向外旋转:
沿着 Z 轴旋转 -60° ,由于 Z 轴就是我们的视觉方向,所以会以轴心为原点,向左逆时针旋转:
另外,上述样式中加了 transition: all 1s;
,这是为了让图形的变化慢一点,方便我们看清它具体是如何变化的,属于动画属性。
立体呈现
之前使用透视 perspective
属性,只能增加近大远小、近实远虚的视觉效果,并不能呈现立体图形效果。
要使子元素实现 立体图形 、真正处于 3D 空间,需要给 父元素 添加 transform-style: preserve-3d;
,其默认值是 flat ,表示子元素处于 2D 平面内呈现,不开启 3D 。
父盒子开启 3D 空间,按需求设置子盒子的位置,位移或旋转,在空间内,转换元素都有自己 独立的坐标轴 ,互不干扰。
示例:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
position: relative;
margin: 100px auto;
width: 200px;
height: 200px;
background-color: lightseagreen;
transition: all 3s;
transform-style: preserve-3d; /* 父元素开启3D空间,呈现立体*/
}
.box div {
position: absolute; /* 定位,后来者居上,即after盒子在前*/
top: 0;
left: 0;
width: 200px;
height: 200px;
}
.bef {
background-color: blue;
transform: translateZ(200px); /* before盒子前移200px*/
}
.aft {
background-color: pink;
}
.box:hover {
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="box">
<div class="bef">before</div>
<div class="aft">after</div>
</div>
</body>
</html>
使用立体呈现实现 3D 导航效果
绿色和橙色部分需要 3 个标签,一个父级标签,绿色和橙色两个子级标签,绿色盒子是立方体的前面,橙色盒子是立方体的上面
(1)实现 html 结构、初始化样式
HTML
<style>
* {
margin: 0;
padding: 0;
text-decoration: none;
list-style: none;
}
.container {
margin: 100px auto;
width: 300px;
height: 40px;
background-color: pink; /* 为了看清效果 */
}
</style>
<div class="container">
<ul>
<li>
<a href="#">首页</a>
<a href="#">index</a>
</li>
<li>
<a href="#">登录</a>
<a href="#">login</a>
</li>
<li>
<a href="#">注册</a>
<a href="#">register</a>
</li>
</ul>
</div>
(2)一行排列、设置宽高颜色
HTML
<style>
.container li {
width: 100px;
height: 100%;
float: left;
line-height: 40px;
text-align: center;
}
li a{
display: inline-block;
width: 100%;
height: 100%;
color: #fff;
font-size: 20px;
}
li a:first-child {
background-color: rgb(0, 128, 0);
}
li a:last-child {
background-color: rgb(255, 165, 0);
}
</style>
(3)子绝父相定位:后来者居上
HTML
<style>
.container li {
position: relative;
width: 100px;
height: 40px;
float: left;
line-height: 40px;
text-align: center;
}
li a {
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 100px;
height: 40px;
color: #fff;
font-size: 20px;
}
</style>
(4)搭建立方体
HTML
<style>
* {
margin: 0;
padding: 0;
text-decoration: none;
list-style: none;
}
.container {
margin: 100px auto;
width: 300px;
height: 40px;
/* background-color: pink; */
}
.container li {
position: relative;
width: 100px;
height: 40px;
float: left;
line-height: 40px;
text-align: center;
transform-style: preserve-3d;
/* 为了便于看到盒子,将li转个角度*/
transform: rotateX(-30deg) rotateY(30deg);
transition: all .5s; /* 效果更明显 */
}
li a {
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 100px;
height: 40px;
color: #fff;
font-size: 20px;
}
li a:first-child {
transform: translateZ(20px); /* 前移 */
background-color: rgb(0, 128, 0);
}
li a:last-child {
transform: rotateX(90deg) translateZ(20px); /* 旋转90°,上移20px*/
background-color: rgb(255, 165, 0);
}
</style>
(5)鼠标悬浮,切换英文
(6)完整代码
完成整体效果之后,删除之前用于辅助的背景颜色、旋转角度等
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>3D导航</title>
<style>
* {
margin: 0;
padding: 0;
text-decoration: none;
list-style: none;
}
.container {
margin: 100px auto;
width: 300px;
height: 40px;
/* background-color: pink; */
}
.container li {
position: relative;
width: 100px;
height: 40px;
float: left;
line-height: 40px;
text-align: center;
transform-style: preserve-3d;
/* 为了便于看到盒子,将li转个角度*/
/* transform: rotateX(-30deg) rotateY(30deg); */
transition: all .5s;
}
li a {
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 100px;
height: 40px;
color: #fff;
font-size: 20px;
}
li a:first-child {
transform: translateZ(20px); /* 前移20px,因为a标签的高度是20px */
background-color: rgb(0, 128, 0);
}
li a:last-child {
transform: rotateX(90deg) translateZ(20px); /* 旋转90°,上移20px,因为a标签的高度是20px*/
background-color: rgb(255, 165, 0);
}
li:hover {
transform: rotateX(-90deg);
}
</style>
</head>
<body>
<div class="container">
<ul>
<li>
<a href="#">首页</a>
<a href="#">index</a>
</li>
<li>
<a href="#">登录</a>
<a href="#">login</a>
</li>
<li>
<a href="#">注册</a>
<a href="#">register</a>
</li>
</ul>
</div>
</body>
</html>
空间缩放
空间缩放 的实现方式与平面缩放一致,只不过在此基础上多了一个 Z 轴缩放: