仅使用 CSS 创建盒盖打开效果

Creating a box flap open effect using only CSS

我尝试使用过渡来创建这种效果。它应该看起来像您正在打开一个盒子。

有2个问题:

  1. 盒子关闭的顺序与打开的顺序相同。有没有办法按照打开的相反顺序关闭盒子,以便盒子回到关闭时的状态?
  2. 由于红色和蓝色襟翼,绿色和黄色襟翼的末端在过渡过程中被隐藏了,所以看起来不是 3D。有没有办法以 3D 方式显示所有襟翼?

我希望解决方案是纯 CSS ,请不要 JavaScript。

#box {
  position: relative;
  top: 170px;
  left: 170px;
  width: 300px;
  height: 300px;
  border: 1px solid black;
  perspective: 800px;
} 
#flap1, #flap2, #flap3, #flap4 {
  position: absolute;
}
#flap1 {
  background-color: red;
  width: 150px;
  height: 300px;
  z-index: 1;
  transform-origin: 0 0;
  transition: transform 1s;
}
#flap2 {
  left: 150px;
  background-color: blue;
  width: 150px;
  height: 300px;
  z-index: 1;
  transform-origin: 100% 0;
  transition: transform 1s ease 0.3s;
}
#flap3 {
  background-color: green;
  width: 300px;
  height: 150px;
  transform-origin: 0 0;
  transition: transform 1s ease 0.6s;
}
#flap4 {
  background-color: yellow;
  top: 150px;
  width: 300px;
  height: 150px;
  transform-origin: 0 100%;
  transition: transform 1s ease 0.9s;
}
#box:hover #flap1{
  transform: rotateY(-170deg);
}
#box:hover #flap2{
  transform: rotateY(170deg);
}
#box:hover #flap3{
  transform: rotateX(170deg);
}
#box:hover #flap4{
  transform: rotateX(-170deg);
}
<html>
  <head>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div id="box">
      <div id="flap1"></div>
      <div id="flap2"></div>
      <div id="flap3"></div>
      <div id="flap4"></div>
    </div>
  </body>
</html>

对于问题 1:

如果您在 :hover 选择器中按正向顺序提供延迟,并在默认选择器中按相反顺序提供延迟,它将实现完全相反的动画效果。

对于问题 2:

修复及解释如下:

  • 对于部分过渡持续时间,绿色和黄色框看起来不像是 3D 效果,因为上面放置了几个 z-index 更高的元素。这可以防止拉伸区域(由于透视旋转)出现,因此它看起来只是 2D(但实际上不是)。为了克服这个问题,我们需要指示浏览器保留变换的 3D 方面。这是使用 transform-style: preserve-3d.
  • 完成的
  • 当我们执行上述操作时,襟翼将以 3D 效果全部打开,但在动画开始和结束附近,当蓝色的过渡实际开始和结束时,我们会看到蓝色襟翼闪烁皮瓣。这似乎是因为 z-index 在使用 3D 变换时失去效果,并且在 z-index 效果消失和 preserve-3D 效果开始之间有一小段时间,在此期间蓝色翻盖暂时落在后面。为了解决这个问题,添加了 z-index: 1(即 translateZ(1px))的 3D 等价物。 Z 轴平移使元素更靠近您的眼睛 1 像素,并使其保持在黄色和绿色襟翼上方。
  • 最后,尽管有上述所有内容,但在悬停动画结束时有一个小故障,绿色襟翼从蓝色襟翼中显示出来。为了克服这个问题,我稍微改变了延迟时间。

(与我最初提到的相反,translateZ(0px) 不是必需的,可以删除。)

#box {
  position: relative;
  top: 170px;
  left: 170px;
  width: 300px;
  height: 300px;
  border: 1px solid black;
  perspective: 800px;
  transform-style: preserve-3d;
}
#flap1, #flap2, #flap3, #flap4 {
  position: absolute;
}
#flap1 {
  background-color: red;
  width: 150px;
  height: 300px;
  z-index: 1;
  transform: translateZ(1px);
  transform-origin: 0 0;
  transition: transform 1s 1.5s;
}
#flap2 {
  left: 150px;
  background-color: blue;
  width: 150px;
  height: 300px;
  z-index: 1;
  transform: translateZ(1px);
  transform-origin: 100% 0;
  transition: transform 1s ease 1s;
}
#flap3 {
  background-color: green;
  width: 300px;
  height: 150px;
  transform-origin: 0 0;
  transition: transform 1s ease 0.5s;
}
#flap4 {
  background-color: yellow;
  top: 150px;
  width: 300px;
  height: 150px;
  transform-origin: 0 100%;
  transition: transform 1s ease;
}
#box:hover #flap1 {
  transform: rotateY(-170deg) translateZ(1px);
  transition: transform 1s ease;
}
#box:hover #flap2 {
  transform: rotateY(170deg) translateZ(1px);
  transition: transform 1s ease 0.5s;
}
#box:hover #flap3 {
  transform: rotateX(170deg);
  transition: transform 1s ease 1s;
}
#box:hover #flap4 {
  transform: rotateX(-170deg);
  transition: transform 1s ease 1.5s;
}
<div id="box">
  <div id="flap1"></div>
  <div id="flap2"></div>
  <div id="flap3"></div>
  <div id="flap4"></div>
</div>