春节创意投稿·使用CSS3制作十二生肖卡牌翻转效果

1,259 阅读5分钟

“ PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛

春节创意投稿·使用CSS3制作十二生肖卡牌翻转效果

1. 展示效果

pic1.gif

2. 步骤拆分

2.1 理解翻牌效果

翻牌效果,即像一张扑克牌一样,有正反两面。当扑克牌朝向正面时,展示的即为带点数的或是大小王的牌,朝向背面时,则我们无法看到牌的正面。套用到页面之中来理解,即两个div容器重叠在一起,达到某个时刻某个div显示,而某个div则隐藏。

2.2 实现翻牌效果

1. 实现两个div重叠的效果

实现两个div重叠的效果我们需要借助两个position属性:relative属性以及absolute属性,我们可以创建一个父级div,里面嵌套着两个子级div,并设置父级div的position属性为relative,而两个子级div的属性为absolute属性。

为什么要这样设置?

父容器设置了relative属性,主要是为了设置了absolute属性的子容器而服务,设置了absolute属性的子容器会根据最近的且position属性不为static的父容器来定位,而由于这一个特性,我们可以使得两个子容器实现重叠的效果。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <div class="cardBox">
    <div class="cardForeCover"></div>
    <div class="cardBackCover"></div>
  </div>
</body>
</html>
<style>
  .cardBox {
    width: 126px;
    height: 224px;
    position: relative;
  }
  
  .cardForeCover {
    width: 100%;
    height: 100%;
    position: absolute;
    background: #5758b2;
  }
  
  .cardBackCover {
    width: 100%;
    height: 100%;
    position: absolute;
    background: #ed4846;
  }
</style>

pic2.jpg

我们可以调试看到这两个div重叠在一起,且后一个子div覆盖了前一个子div。

2. 使用transform属性进行旋转

我们可以利用transform属性中的rotateY(参数)属性来设定两个子div绕着Y轴旋转的角度。在这里我们要思考一下下面这副图所要传达的含义。

pic3.png

假设红色为背面,紫色为正面,即我们要实现将红色的一面绕着Y轴从0度旋转至180度,紫色的一面则要绕着Y轴从-180度旋转至0度。在这里可能存在一个疑惑:为什么紫色的一面不能绕着Y轴从180度旋转到0度呢?

红色的一面绕着Y轴从0度旋转至180度,此时红色的一面是以逆时针的形式绕着Y轴进行旋转。而若此时紫色的一面绕着Y轴若从180度旋转至0度,则此时是以顺时针的形式绕着Y轴进行旋转。而我们要实现的是让红色的一面与紫色的一面都绕着相同的方向进行旋转,因此让紫色的一面绕着Y轴从-180度旋转至0度,这样是以顺时针的形式绕着Y轴旋转,因此着就能避免二者交叉或重叠。

因此我们要指定子级div初始化时相对于Y轴的角度,并为父类div编写伪类,指定鼠标移动至父级div时,子级div相对于Y轴的所变化的角度。

.cardForeCover {
  width: 100%;
  height: 100%;
  position: absolute;
  background: #cd4a40;
  transform: rotateY(-180deg); /*初始化表示正面的子级div相对于Y轴角度*/ 
}

.cardBackCover {
  width: 100%;
  height: 100%;
  position: absolute;
  background: cadetblue;
  transform: rotateY(0deg); /*初始化表示背面的子级div相对于Y轴的角度*/
}

.cardBox:hover .cardForeCover {
  transform: rotateY(0deg); /*指定鼠标移动至父级div时,表示正面的子级div相对于Y轴的角的角度*/
}

.cardBox:hover .cardBackCover {
  transform: rotateY(180deg); /*指定鼠标移动至父级div时,表示背面的子级div相对于Y轴的角度*/
}

3. 使用backface-visibility隐藏表示背面的子级div的背面

至此,我们来演示一下到目前为止我们所作的效果:

pic4.gif

我们发现,鼠标移动至父级div中,并没有任何效果,移动出父级div中,也没有任何效果,这是什么情况?此时,我们要利用到backface-visibility属性,backface-visibility属性表示当一个元素进行旋转时,其背面是否可见。

因此,当表示正面的子级div或表示背面的子级div沿着Y轴旋转到指定角度时,我们都需要对其背面进行隐藏,所以我们需要在即在.cardForeCover类以及.cardBackCover类中添加如下属性实现此效果。

backface-visibility: hidden; /*设置div隐藏其背面*/

再次演示一下到目前位置我们所作的效果:

pic5.gif

4. 为div的旋转添加过渡效果

我们可以使用transition来为div的旋转添加过渡效果。transition是一个由四个参数缩写的属性,从左至右,其四个参数分别表示需要设置的过渡效果的css属性名,过渡效果的持续时间,过渡效果属性名,以及过渡效果的延时时间。 我们现在在.cardForeCover类以及.cardBackCover类中添加如下属性实现此过渡效果。

transition: transform 0.5s ease-in-out; /*设置div旋转时所应用的过渡效果*/

此时,演示一下添加了过渡效果的div旋转时的效果:

pic6.gif

5. 添加perspective属性加强3D效果

通过前面4个步骤我们已经基本完成了卡片翻牌的效果,现在有一个问题:即我们看到的卡牌翻转的效果不太立体。

我们可以通过添加perspective属性为div旋转时加大透视点与div的距离,以此来加强3D效果。

我们现在在.cardBox类中添加如下属性实现此加强3D的效果,其数值一般选取大于或等于父级div的高度。

perspective: 224px;

让我们来展示最终的效果:

pic7.gif

3.完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>application</title>
</head>
<body>
  <div class="flexBox">
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image1.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image2.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image3.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image4.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image5.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image6.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image7.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image8.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image9.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image10.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image11.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
    <div class="cardBox">
      <div class="cardForeCover">
        <img src="image/image12.png">
      </div>
      <div class="cardBackCover">
        <div></div>
      </div>
    </div>
  </div>
</body>
</html>
<style>
  html, body {
    margin: 0px;
    padding: 0px;
  }
  
  .flexBox {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
  }
  
  img {
    width: 96px;
    height: 96px;
  }
  
  .cardBox div {
    /*美化子级div*/
    border-radius: 5px;
    color: whitesmoke;
    font-size: 32px;
    /*设置flex布局,使图片以及文字居中*/
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  .cardBox {
    width: 126px;
    height: 224px;
    position: relative;
    perspective: 224px;
    margin: 20px;
  }
  
  .cardForeCover {
    width: 100%;
    height: 100%;
    position: absolute;
    background: #5758b2;
    transform: rotateY(-180deg); /*初始化表示正面的子级div相对于Y轴角度*/
    transition: transform 0.5s ease-in-out; /*设置div旋转时所应用的过渡效果*/
    backface-visibility: hidden; /*设置div隐藏其背面*/
  }
  
  .cardBackCover {
    width: 100%;
    height: 100%;
    position: absolute;
    background: #ed4846;
    transform: rotateY(0deg); /*初始化表示背面的子级div相对于Y轴的角度*/
    transition: transform 0.5s ease-in-out; /*设置div旋转时所应用的过渡效果*/
    backface-visibility: hidden; /*设置div隐藏其背面*/
  }

  .cardBox:hover .cardForeCover {
    transform: rotateY(0deg); /*指定鼠标移动至父级div时,表示正面的子级div相对于Y轴的角的角度*/
  }

  .cardBox:hover .cardBackCover {
    transform: rotateY(180deg); /*指定鼠标移动至父级div时,表示背面的子级div相对于Y轴的角度*/
  }
</style>

作者:通雄

版权声明:本文为原创文章,未经本人允许不得转载。