今天学习了CSS3中关于3D效果的相关知识,并实现了一个可以两面翻转盒子。但在实现完之后发现,在翻转时,前后盒子会不停的替换,直到动画完成。
效果如下
之后再次重新观察代码发现,因为我的盒子结构是这样子的
<body>
<div class="box">
<div class="front">前面的盒子</div>
<div class="back">背面的盒子</div>
</div>
</body>
给前面盒子和后面盒子同时设置绝对定位,应该back盒子会压住front盒子才对,我的front盒子并没有设置z-index
属性。之后我又给back盒子设置了z-index
属性,发现已经不管用了,之后通过网上查找,发现,因为使用transform
时会创建更高层级的stacking context
(堆叠上下文),会导致z-index
属性失效。之后就想通过translateZ
来把后面盒子放到顶上来,但设置之后出现了下面的情况。
代码:
.back {
background-color: coral;
transform: rotateY(180deg) translateZ(100px);
}
效果如下:
突然就没有出现前面疯狂闪烁的情况了。但我设置的是正数,但back是向后走了,原来rotateY
把坐标轴都转了一个方向。导致之前闪烁的可能就是因为创建新的堆叠上下文时,和正常的有点重合,导致了显示时出现了一些问题,所以之后通过给之中一个盒子设置一个translateZ(1px)
,就可以比较好的解决这个问题。
解决方案1:
代码如下
<!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>
body {
perspective: 500px;
}
.box {
position: relative;
width: 300px;
height: 300px;
margin: 200px auto;
transform-style: preserve-3d;
transition: all 1s;
}
.box:hover {
transform: rotateY(180deg);
}
.front,
.back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: white;
border-radius: 50%;
text-align: center;
line-height: 300px;
}
.front {
background-color: skyblue;
}
.back {
background-color: coral;
transform: rotateY(180deg) translateZ(1px); /*我给back盒子设置了一个1px的z轴距离*/
}
</style>
</head>
<body>
<div class="box">
<div class="front">前面的盒子</div>
<div class="back">背面的盒子</div>
</div>
</body>
</html>
效果如下:
解决方案2:
但这种方案个人觉得并不是最完美的,仔细看是可以看到在翻转到90度的时候会有一条很细的橙色线,就是因为设置了z轴的距离。之后又知道了一个backface-visibility:hidden
属性,这个属性就是将旋转图片的背面隐藏,既然浏览器都不知道显示哪一个,我就显示一个把后面的隐藏起来,很好的解决了这个问题,(但要记得给front盒子和back盒子都要加!!)
代码如下:
<!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>
body {
perspective: 500px;
}
.box {
position: relative;
width: 300px;
height: 300px;
margin: 200px auto;
transform-style: preserve-3d;
transition: all 1s;
}
.box:hover {
transform: rotateY(180deg);
}
.front,
.back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: white;
border-radius: 50%;
text-align: center;
line-height: 300px;
backface-visibility: hidden;
}
.front {
background-color: skyblue;
}
.back {
background-color: coral;
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="box">
<div class="front">前面的盒子</div>
<div class="back">背面的盒子</div>
</div>
</body>
</html>
效果如下:
如果发现什么问题,或者分析的有问题的地方,请各位指正。