perspective:定义3D元素距视图的距离,以像素计。当为元素定义perspective属性时,其子元素就会获得透视效果,而不是元素本身

给父元素设置perspective,子元素就获得了透视效果,符合近大远小的原则,perspective值越大,距离屏幕就越远,看起来就越小

<div class="wrapper">
    <div class="item">item</div>
</div>
body {
    margin: 0;
}
.wrapper {
    margin: 100px
    height: 200px;
    width: 200px;
    border: 1px solid #000;
    perspective: 600px;
}
.item {
    background: pink;
    color: #fff;
    width: 200px;
    height:200px;
    line-height: 100px;
    text-align: center;
    transform: rotateX(45deg);
}

效果:

Current request is not a multipart request前端 前端perspective_3D


不同perspective效果:

Current request is not a multipart request前端 前端perspective_3d_02


虽然现在看起来好像有点3D的效果,但其实元素还是2d的,我们用两个item,以y轴旋转,看看效果:

.wrapper {
    position: relative;
    margin: 100px;
    height: 200px;
    width: 200px;
    border: 1px solid #000;
    perspective: 600px;
}
.item {
    position: absolute;
    top: 0;
    left: 0;
    color: #fff;
    width: 200px;
    height:200px;
    line-height: 100px;
    text-align: center;
    
}
.one {
    background: pink;
    transform: rotateX(45deg);
}
.two {
    background: royalblue;
    transform: rotateX(-45deg);
}
<div class="wrapper">
    <div class="item one">one</div>
    <div class="item two">two</div>
</div>

效果:没有中间有交叉的感觉

Current request is not a multipart request前端 前端perspective_2d_03


再沿y轴旋转看看,从45deg向90deg旋转:

Current request is not a multipart request前端 前端perspective_3d_04


可以看到,其实y轴看,还是2d的,没有立体的厚度

要想属性都有3D空间,保留3d效果,还需要在容器上设置一个属性:transform-style

在父级容器.wrapper上设置:

transform-style: preserve-3d;

效果:item子元素沿x轴旋转

Current request is not a multipart request前端 前端perspective_animation_05


容器wrapper沿y轴旋转45deg:

Current request is not a multipart request前端 前端perspective_2d_06


3d效果就出来了

transform-style指定嵌套元素是怎样在三维空间中呈现
transform-style: flat | preserve-3d;
注:设置了transform-style: preserve-3d的元素,不能防止子元素溢出,即不能设置overflow: hidden;,否则preserve-3d失效

现在我希望让这两个item旋转起来,就像摇水车一样,这里我写了一个animation动画

@keyframes move {
    0% {
        transform: rotateX(0);
    }
    100% {
        transform: rotateX(360deg);
    }
}

并在wrapper上添加这个动画:

animation: move 5s linear infinite;

效果:

Current request is not a multipart request前端 前端perspective_2d_07


让wrapper沿y轴旋转一些角度:

Current request is not a multipart request前端 前端perspective_3D_08

可以看到,两个item都因为近大远小的原因,有一半大一半小,这是设置perspective的效果,因此,如果想要让item交叉的两半一样大,就需要注销掉父级容器wrapper的perspective,效果如下:

Current request is not a multipart request前端 前端perspective_css3_09


在wrapper外再包裹一个div.box,让box设置perspective,让转动有3d空间:

.box {
    perspective: 600px;
    height: 200px;
    width: 200px;
    margin: 100px;
}
.wrapper {
    position: relative;
    height: 200px;
    width: 200px;
    border: 1px solid #000;
    /* perspective: 600px; */
    transform-style: preserve-3d;
    animation: move 5s linear infinite;
}

Current request is not a multipart request前端 前端perspective_3D_10


看各个div:

Current request is not a multipart request前端 前端perspective_2d_11


因此,如果你想让某个元素是规则方正的、没有近大远小效果的,就不要在这个元素的父级设置perspective如果我们直接在body上加perspective,而不是另外嵌套一个width200px的box,效果怎么样?

Current request is not a multipart request前端 前端perspective_animation_12


好像方向往左边偏了些,不是正对着屏幕的这个效果和把box的width设成600px(item的width是200px)差不多

为了效果明显,把border放在box中

Current request is not a multipart request前端 前端perspective_css3_13


其实是因为,默认视角是从容器(box)中心出发的,box宽度为600px,从中心处看向item,所以看起来像往左偏,侧面一样

把视角中心调整一下即可

perspective-origin视点的位置
perspective-origin: x y; 默认50% 50%

在box上添加:

perspective-origin: 100px 100px;

Current request is not a multipart request前端 前端perspective_3d_14


视点在item中心,这样就正了

也可以设center top left这些backface-visibility属性定义当元素背面是否可见

backface-visibility:visible | hidden;

在item设置hidden

当翻了一个面,到了背面,就看不见,只有是正面时才看得见

Current request is not a multipart request前端 前端perspective_3d_15