How to flip multiple divs using CSS?

好久不见. 提交于 2019-12-04 12:52:41

The flip animation when used with two elements is a very simple one because there is one back side and one front side. But when the same needs to be implemented with many elements then it becomes extra complex because you need to maintain 3 states which are as follows:

  • Flipped - This is when a block comes into view and the rotation is 0 degree (basically no rotation).
  • Before - This is the state of elements which are prior to the flipped element. In this state the block is rotated 180 degree in one direction.
  • After - This is the state of elements which are after the flipped element. In this state the block is rotated 180 degree in the opposite direction.

So basically when a link is clicked, the block before it is rotated from 0 to 180 degree, the target block itself is rotated from -180 degree to 0 degree (and next element remains at -180 degree). Doing these things provide it the look and feel of having a chain rotation.

$(".nav li a").on("click", function() {
  var activeTab = $(this).attr("href");
  $('#card > div').removeClass('flipped after before');
  $(activeTab).addClass('flipped');
  $(activeTab).prevAll('.flipper').addClass('before');
  $(activeTab).nextAll('.flipper').addClass('after');
  return false;
});
.container {
   width: 500px;
   height: 360px;
   position: relative;
   margin: 0 auto 40px;
   border: 1px solid #CCC;
   -webkit-perspective: 800px;
   -moz-perspective: 800px;
   -o-perspective: 800px;
   perspective: 800px;
 }
 #card {
   width: 100%;
   height: 100%;
   position: absolute;
   -webkit-transform-style: preserve-3d;
   -moz-transform-style: preserve-3d;
   -o-transform-style: preserve-3d;
   transform-style: preserve-3d;
 }
 #card .flipper {
   display: block;
   height: 100%;
   width: 100%;
   line-height: 260px;
   color: white;
   text-align: center;
   font-weight: bold;
   font-size: 140px;
   position: absolute;
   -webkit-transition: -webkit-transform 1s, opacity 1s;
   -moz-transition: -moz-transform 1s, opacity 1s;
   -o-transition: -o-transform 1s, opacity 1s;
   transition: transform 1s, opacity 1s;
   -webkit-backface-visibility: hidden;
   -moz-backface-visibility: hidden;
   -o-backface-visibility: hidden;
   backface-visibility: hidden;
   background: blue;
   opacity: 0;
 }
 #card .flipper:nth-child(2n) {
   background: red;
 }
 #card .flipper.flipped {
   -webkit-transform: rotateX(0deg);
   -moz-transform: rotateX(0deg);
   -o-transform: rotateX(0deg);
   transform: rotateX(0deg);
   z-index: 1;
   opacity:1;
 }
 #card .flipper.before {
   -webkit-transform: rotateX(180deg);
   -moz-transform: rotateX(180deg);
   -o-transform: rotateX(180deg);
   transform: rotateX(180deg);
 }
 #card .flipper.after {
   -webkit-transform: rotateX(-180deg);
   -moz-transform: rotateX(-180deg);
   -o-transform: rotateX(-180deg);
   transform: rotateX(-180deg);
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul class="nav">
  <li><a href="#home">home</a>
  </li>
  <li><a href="#about">about</a>
  </li>
  <li><a href="#work">work</a>
  </li>
  <li><a href="#contact">contact</a>
  </li>
</ul>
<section class="container">
  <div id="card">
    <div class="flipper flipped" id="home">home</div>
    <div class="flipper after" id="about">about</div>
    <div class="flipper after" id="work">work</div>
    <div class="flipper after" id="contact">contact</div>
  </div>
</section>

Note: The jQuery code can be optimized further but I will leave the fine tuning part to you.

I believe this is what you're looking for.

$(".nav li").on("click", function(){
    
    var activeTab = $(this).find("a").attr("href");
    if($(activeTab).hasClass('current-flipper'))
        return;
    //  alert(activeTab);
    $("#card").find('div').removeClass('current-flipper');
    $(activeTab).addClass('current-flipper');
    $("#card").toggleClass("flipped");    
    return false;
});
.flipper{
    display: none;
}

.current-flipper.flipper{
    display: block;
}

.container {
      width: 500px;
      height: 360px;
      position: relative;
      margin: 0 auto 40px;
      border: 1px solid #CCC;
      -webkit-perspective: 800px;
         -moz-perspective: 800px;
           -o-perspective: 800px;
              perspective: 800px;
    }

    #card {
      width: 100%;
      height: 100%;
      position: absolute;
      -webkit-transition: -webkit-transform 1s;
         -moz-transition: -moz-transform 1s;
           -o-transition: -o-transform 1s;
              transition: transform 1s;
      -webkit-transform-style: preserve-3d;
         -moz-transform-style: preserve-3d;
           -o-transform-style: preserve-3d;
              transform-style: preserve-3d;
    }

    #card.flipped {
      -webkit-transform: rotateX( 360deg );
         -moz-transform: rotateX( 360deg );
           -o-transform: rotateX( 360deg );
              transform: rotateX( 360deg );
    }

    #card .flipper {
      height: 100%;
      width: 100%;
      line-height: 260px;
      color: white;
      text-align: center;
      font-weight: bold;
      font-size: 140px;
      position: absolute;
      -webkit-backface-visibility: hidden;
         -moz-backface-visibility: hidden;
           -o-backface-visibility: hidden;
              backface-visibility: hidden;
    }
.flipper{ background:#963}
#home{
    background:red;
}
#about{
    background:blue;
}
#work{
    background:green;
}
#contact{
    background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav">
	<li><a href="#home">home</a></li>
    <li><a href="#about">about</a></li>
    <li><a href="#work">work</a></li>
    <li><a href="#contact">contact</a></li>
</ul>


 <section class="container">
    <div id="card">
      <div class="flipper current-flipper" id="home">home</div>
      <div class="flipper" id="about">about</div>
      <div class="flipper" id="work">work</div>
      <div class="flipper" id="contact">contact</div>
    </div>
  </section>

I think you're only seeing the last two because they're stacking on top of the first two. Essentially the cards themselves (elements with .front/.back classes) are staying still while you're rotating #card around them.

Perhaps you can try rotating the .front/.back elements independently. It means manually handling the interaction but in my opinion it'd easier to reason about.

Hope that helps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!