最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - CSS3 Card Flip and Expand - Stack Overflow

programmeradmin1浏览0评论

I'm trying to have a collection of cards/divs within a container. When a card/div is clicked, it should flip horizontally and expand to take up the entire space within the container (basically changing the size of the card/div to 100% x 100% when clicked). I'm unsure if this is possible or not, as all of the examples that I've seen out there typically involve the card/div remaining the same size.

Here's the fiddle I tried working with, but I can't get the basic flipping functionality: /

$('.card').click(function(){
  $(this).addClass('flipped').mouseleave(function(){
    $(this).removeClass('flipped');
  });
  return false;
});
.cards {
  width: 100%;
  height: 100%;
  background: gray;
  padding: 10px;
  box-sizing: border-box;
  
  position: relative;
  -webkit-perspective: 800;
  perspective: 800;
}

.cards .card {
  -webkit-transform-style: preserve-3d;
  -webkit-transition: 0.5s;
}

.flip .card .face {
  width: 100%;
  position: absolute;
  -webkit-backface-visibility: hidden ;
  z-index: 2;
}

.flip .card .front {
  position: absolute;
  z-index: 1;
  background: black;
}

.flip .card .back {
  -webkit-transform: rotatex(-180deg);
  background: white;
}

.cards .card.flipped {
  -webkit-transform: rotatex(-180deg);
}

.card {
  width: 100%;
  background: lightgray;
  padding: 6px;
  margin: 10px 0;
  box-sizing: border-box;
  
  cursor: pointer;
  
  position: relative;
  position: absolute;
  transform-style: preserve-3d;
  transition: transform 1s;
}

.card:nth-of-type(1) {
  margin-top: 0;
}

.card figure {
  margin: 0;
  display: block;
  position: absolute;
  width: 100%;
  backface-visibility: hidden;
}
<script src=".1.1/jquery.min.js"></script>
<div style="width: 400px; height: 600px;">
  <div class="cards">
    <div class="card">
      <div class="face front">Card 1 Front</div>
      <div class="face back">Card 2 Back</div>
    </div>
    <div class="card">
      <div class="face front">Card 2 Front</div>
      <div class="face back">Card 2 Back</div>
    </div>
    <div class="card">
      <div class="face front">Card 3 Front</div>
      <div class="face back">Card 3 Back</div>
    </div>
  </div>
</div>

I'm trying to have a collection of cards/divs within a container. When a card/div is clicked, it should flip horizontally and expand to take up the entire space within the container (basically changing the size of the card/div to 100% x 100% when clicked). I'm unsure if this is possible or not, as all of the examples that I've seen out there typically involve the card/div remaining the same size.

Here's the fiddle I tried working with, but I can't get the basic flipping functionality: https://jsfiddle/4dazznb5/

$('.card').click(function(){
  $(this).addClass('flipped').mouseleave(function(){
    $(this).removeClass('flipped');
  });
  return false;
});
.cards {
  width: 100%;
  height: 100%;
  background: gray;
  padding: 10px;
  box-sizing: border-box;
  
  position: relative;
  -webkit-perspective: 800;
  perspective: 800;
}

.cards .card {
  -webkit-transform-style: preserve-3d;
  -webkit-transition: 0.5s;
}

.flip .card .face {
  width: 100%;
  position: absolute;
  -webkit-backface-visibility: hidden ;
  z-index: 2;
}

.flip .card .front {
  position: absolute;
  z-index: 1;
  background: black;
}

.flip .card .back {
  -webkit-transform: rotatex(-180deg);
  background: white;
}

.cards .card.flipped {
  -webkit-transform: rotatex(-180deg);
}

.card {
  width: 100%;
  background: lightgray;
  padding: 6px;
  margin: 10px 0;
  box-sizing: border-box;
  
  cursor: pointer;
  
  position: relative;
  position: absolute;
  transform-style: preserve-3d;
  transition: transform 1s;
}

.card:nth-of-type(1) {
  margin-top: 0;
}

.card figure {
  margin: 0;
  display: block;
  position: absolute;
  width: 100%;
  backface-visibility: hidden;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width: 400px; height: 600px;">
  <div class="cards">
    <div class="card">
      <div class="face front">Card 1 Front</div>
      <div class="face back">Card 2 Back</div>
    </div>
    <div class="card">
      <div class="face front">Card 2 Front</div>
      <div class="face back">Card 2 Back</div>
    </div>
    <div class="card">
      <div class="face front">Card 3 Front</div>
      <div class="face back">Card 3 Back</div>
    </div>
  </div>
</div>

Share Improve this question asked Feb 18, 2016 at 5:40 BlockisBlockis 581 silver badge6 bronze badges 3
  • You want .card div full height when click? – ketan Commented Feb 18, 2016 at 5:52
  • @ketan: Ideally, when you click the div, it has a flip effect, and consumes the full height. So, yes! – Blockis Commented Feb 18, 2016 at 6:25
  • @Blockis there is a card flip I did for the track listings on this site: etonmessy. I'm not sure if it will help you or not. But I thought I would also just give a heads up on animating to full width - css animating by anything other than transform/opacity does tend to be a little jerky. I'm not sure you'll get the effect you want with just transform: scale(); , but if not, you may want to give it some consideration. – Paul Thomas Commented Feb 18, 2016 at 9:47
Add a ment  | 

3 Answers 3

Reset to default 5

Since Tambo's backfaces were better (allowing html content), I made this mix with our answers (tested with success on Mozilla and Chrome):

$('.card').click(function(){  
 
  if (!$(this).hasClass("flipped")) {
  $( ".face" ).addClass( 'off' );
  $( this ).children( ".face" ).removeClass( 'off' );
  $( this ).parent( ".cards" ).addClass( 'big' );
  $( this ).addClass('flipped');

  } else {
 
  $( ".face" ).removeClass( 'off' );
  $( ".cards" ).removeClass( 'big' );
  $( this ).removeClass('flipped'); 
}
  

});
body {
height:100vh;
width:100vw;
margin:0px;
}

#container {
position: relative;
background: skyblue;
height:100%;
width:60%;
overflow: hidden;
margin:auto;
}

.off {
  color: rgba(0, 0, 0, 0.0) !important;
  background: rgba(230, 230, 250, 0.0) !important;
  -webkit-transition: all 2s; /* Safari */
  transition: all 2s;
}

.cards {
  -webkit-perspective: 900px;
  -moz-perspective: 900px;
  perspective: 900px;
  width: 80%;
  height: 20%;
  position: absolute;
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
  margin-left: 10%;
  margin-right: 10%;
 }
 
.cards .card.flipped {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  height: 100%;
  z-index: 100;
}

.cards .card {
  width: 100%;
  height: 100%;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
}

.cards .card .face {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-backface-visibility: hidden ;
  -moz-backface-visibility: hidden ;
  backface-visibility: hidden ;
  z-index: 2;
  font-size: 2em;
  font-family: arial, sans-serif;
  text-align: center;
  -webkit-transition: all 0.5s; /* Safari */
  transition: all 0.5s;
}

.cards .card .front {
  position: absolute;
  background: tomato;
  z-index: 1;
}

.cards .card .back {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  background: gold;
}

.cards .card .front,
.cards .card .back{
  cursor: pointer;
}

.big {
height:100%;
width:100%;
top: 0% !important;
margin-left: 0%;
margin-right: 0%;
z-index:100;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=container>

<div class=cards style="top:0px"> 
<div class=card> 
   <div class="face front"> 
      Card 1 Front
    </div> 
    <div class="face back"> 
      Card 1 Back
    </div> 
  </div> 
</div> 

<div class=cards style="top:25%"> 
    <div class=card> 
    <div class="face front"> 
      Card 2 Front
    </div> 
    <div class="face back"> 
      Card 2 Back
    </div> 
  </div> 
</div>

 <div class=cards style="top:50%"> 
   <div class=card> 
    <div class="face front"> 
      Card 3 Front
    </div> 
    <div class="face back"> 
      Card 3 Back
    </div> 
  </div> 
</div>

<div class=cards style="top:75%">
   <div class=card> 
    <div class="face front"> 
      Card 4 Front
    </div> 
    <div class="face back"> 
      Card 4 Back
    </div> 
  </div> 
</div> 

</div>

Just add !important to the new 'flipped' class attributes overwrites the old ones. The javascript line $( ".item" ).not( this ).addClass( 'off' ) removes the other cards when one is selected. The absolute position let everything on its place. The active card have a higher z-index to ensures that other cards will not activate the 'mouseleave' trigger. UPDATE: finally working 100% on Mozilla and Chrome. ps: a click opens the card and another click closes it.

$('.item').click(function(){  
 
  if (!$(this).hasClass("flipped")) {
  $( ".item" ).not( this ).addClass( 'off' );
  $( this ).addClass('flipped');

  } else {
 
  $( ".item" ).removeClass( 'off' );
  $( this ).removeClass('flipped'); 
}
  

});
.off {
  color: rgba(0, 0, 0, 0.0) !important;
  background: rgba(230, 230, 250, 0.0) !important;
}

.cards {
  width: 100%;
  height: 100%;
  background: lavender;
  position: relative;
  -webkit-perspective: 900px;
  perspective: 900px;
}

.flipped {
  top: 0% !important;
  height: 100% !important;
  width: 100% !important;
  -webkit-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
  color: rgba(0, 0, 0, 0.0);
  z-index:100;
  -webkit-transform-style: preserve-3d;
  background: tomato;
}

.flipped:after {
  content: 'More text on here.';
    right: 0px;
    bottom: 0px;
    position: absolute;
    top: 0px;
    left: 0px;
  color: rgba(0, 0, 0, 1.0);
  -webkit-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  -webkit-backface-visibility: hidden;
  -webkit-transform-style: preserve-3d;
  background: gold;
}

.card {
  height: 22%;
  width: 100%;
  box-sizing: border-box;  
  cursor: pointer;  
  -webkit-transition: all 1s; /* Safari */
  transition: all 1s;
  display: block;
  position: absolute;
  background: tomato;
}

.aaa {
top:0%;  
}

.bbb {
top:26%;  
}

c {
top:52%;  
}

.ddd {
top:78%;  
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width: 400px; height: 600px;">
  <div class="cards">
    <div class="card item aaa">
      <div class="face front">Some text on here.</div>
    </div>
    <div class="card item bbb">
      <div class="face front">Some text on here.</div>
    </div>
      <div class="card item ccc">
      <div class="face front">Some text on here.</div>
    </div>
      <div class="card item ddd">
      <div class="face front">Some text on here.</div>
    </div>
  </div>
</div>

Just play with Element.classList and CSS transitions

// Function to flip the card and expand the content 
function flipMe() {
  console.log(this.innerHTML);
  var card = this.querySelector('.card');
  card.classList.add('flipped');
  // this handler will be executed every time the cursor is moved off the card
  card.addEventListener("mouseout", function( event ) {   
    this.classList.remove('flipped');
  }, false);
}
// Define our variables
var cardWrapper = document.querySelector('.cardWrapper');
 

cardWrapper.addEventListener("click", flipMe, false);
:root {
 background: #CAC8CC;
}
.cardWrapper {
  -webkit-perspective: 800;
  -moz-perspective: 800;
  perspective: 800;
  width: 400px;
  height: 300px;
  position: relative;
  margin: 100px auto;
}
.cardWrapper .card.flipped {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  height: 100%;
}
.cardWrapper .card {
  width: 100%;
  height: 100px;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transition: .5s;
  -moz-transition: .5s;
  transition: .5s;
}
.cardWrapper .card .face {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-backface-visibility: hidden ;
  -moz-backface-visibility: hidden ;
  backface-visibility: hidden ;
  z-index: 2;
  font-size: 4em;
  text-align: center;
}
.cardWrapper .card .front {
  position: absolute;
  background: black;
  color: white;
  z-index: 1;
}
.cardWrapper .card .back {
  -webkit-transform: rotatex(-180deg);
  -moz-transform: rotatex(-180deg);
  transform: rotatex(-180deg);
  background-color: #0095ff;
}
.cardWrapper .card .front,
.cardWrapper .card .back{
  cursor: pointer;
}
<div class=cardWrapper> 
  <div class=card> 
    <div class="face front"> 
      Card 1 Front
    </div> 
    <div class="face back"> 
      Card 1 Back
    </div> 
  </div> 
</div> 

发布评论

评论列表(0)

  1. 暂无评论