Chris Nielsen
Chris Nielsen

Reputation: 849

CSS Flip Animation reset on every click

I am using David Walsh css flip effect: http://davidwalsh.name/css-flip

I have this working onClick with a JavaScript function called showCard(). See the codePen here: https://codepen.io/Chris_Nielsen/pen/YaWmMe

When you first click the button, it animates correctly (opens from left to right). However, when you click the button again, it closes animates from right to left. The third time the button is clicked it opens again animates correctly (from left to right) again.

What I want to do is get this to re-open from left to right every time.

Can someone point out how I can make this work? I have worked on this for 2 hours and am stumped.

The Code:

function showCard() {
  document.querySelector("#errorMessage").classList.toggle("flip");
}
body {
  background: #575955;
  color: white;
}
.error-box {
  width: 380px;
  height: 110px;
  background: #fff;
  border: solid 1px #B71C1C;
  border-radius: 9px;
  font-family: 'Raleway', sans-serif;
  font-size: 1.6rem;
  color: #B71C1C;
  text-align: center;
  padding: 30px;
}

/* entire container, keeps perspective */
.flip-container {
	perspective: 1000px;
}
/* flip the pane when hovered */
.flip-container.flip .flipper {
  visibility: visible;
  transform: rotateY(90deg);
  /* transform: rotateY(90deg); */
}

.flip-container, .front, .back {
	width: 320px;
	height: 480px;
}

/* flip speed goes here */
.flipper {
	transition: .35s;
	transform-style: preserve-3d;
	position: relative;
}

/* hide back of pane during swap */
.front, .back {
	backface-visibility: hidden;
	position: absolute;
	top: 0;
	left: 0;
}

/* front pane, placed above back */
.front {
	z-index: 2;
	/* for firefox 31 */
	transform: rotateY(-90deg);
}

/* back, initially hidden pane */
.back {
	transform: rotateY(180deg);
}
<h1>Click the button below to see the <br>animated alert.</h1>
<div class="flip-container" id="errorMessage" >
    <div class="flipper">
        <!-- text here will rotate --> 
        <div class="front">
            <!-- front content --> 
            <br><br><br>
            <div class="error-box">
                Email address or password <br>
                Incorrect. <br>
                Please Try Again.
            </div>      
        </div>
        <div class="back">
            <!-- back content -->
        </div>
    </div>    
</div>
<input type="button" value="Show card" onClick="showCard();"> 
       

Upvotes: 0

Views: 779

Answers (2)

Chris Nielsen
Chris Nielsen

Reputation: 849

Okay, I finally got this working so that every time the button is clicked the card opens from right to left. It took a combination of @Jamie D's idea above about removing and re-adding classes with the idea of using a jQuery function with a timer that automatically reclicks the button.

Solution can be seen on codepen here: https://codepen.io/Chris_Nielsen/pen/LdWPPG

Here is the solution code.

var card = document.querySelector("#errorMessage");
var container = document.querySelector('.flip-container');
var isOpen = false;

function showCard() {
  if (!isOpen) {
    container.style.visibility = "visible";
    card.classList.add("flip");
    document.querySelector(".flipper").classList.toggle("flip");
    isOpen = true;
  } else if (isOpen) { 
    card.classList.toggle("flip");
    isOpen = false;
    clickAgain();
  }
}

function clickAgain(){
  setTimeout(function() {
    $(document).ready(function(){
      $("#b1").click()
    });
  }, 350);
}
body {
  background: #575955;
  color: white;
}
.error-box {
  width: 380px;
  height: 110px;
  background: #fff;
  border: solid 1px #B71C1C;
  border-radius: 9px;
  font-family: 'Raleway', sans-serif;
  font-size: 1.6rem;
  color: #B71C1C;
  text-align: center;
  padding: 30px;
}

/* Hide the flip container to start */
.flip-container {
	perspective: 1000px;
  visibility: hidden;
}
.flip-container.flip .flipper {
  transform: rotateY(90deg);
  transition: 0.35s;
}

.flip-container, .front, .back {
	width: 320px;
	height: 200px;
}

/* flip speed goes here */
.flipper {
	transition: 0s;
	transform-style: preserve-3d;
	position: relative;
}

/* hide back of pane during swap */
.front, .back {
	backface-visibility: hidden;
	position: absolute;
	top: 0;
	left: 0;
}

/* front pane, placed above back */
.front {
	z-index: 2;
	/* for firefox 31 */
	transform: rotateY(-90deg);
}

/* back, initially hidden pane */
.back {
	transform: rotateY(90deg);
/*   transform: rotateY(180deg); */
}
<h1>Click the button below to see the <br>animated alert.</h1>
<div class="flip-container" id="errorMessage" >
  <div class="flipper">
   <!-- text here will rotate --> 
		<div class="front">
			<!-- front content --> 
      <div class="error-box">
      Email address or password <br>
      Incorrect. <br>
      Please Try Again.
      </div>      
		</div>
		<div class="back">
			<!-- back content -->
		</div>
	</div>      
</div>
<input type="button" id="b1" value="Show card" onClick="showCard();"> 

Upvotes: 0

Jamie D
Jamie D

Reputation: 11

I think it will help to explain a little bit of what is going on here in the code you have now. In short, you've created an action based on a CSS class that fires on a click. The important part to note here is that this action is based on the addition of a class.

visually...your html looks something like this (using alternate elements here for simplification).

<element class="class1">some text</element>

then when you click the button, this changes the HTML markup to look something like this...

<element class="class1 class2">some text</element>

which in turn, hits your css sheet which now fires off the action that you want...in your case...flipping the card.

So the reason why your card is flipping the direction you want on first click, and then flipping back the opposite direction on your second click, is because you are simply adding a class that says, "turn me 90 degrees", and then on the 2nd click, removing that same class which tells your CSS to basically "undo" that move.

I'm not sure what the best approach will be if you want to continue to use what David Walsh wrote, plug and play, because it wasn't really designed to do what you're looking for. One approach may be to add a second class that completes another 90degree rotation on click 2, and then hide the element while you remove the two classes that undo your rotations.

Update 1 - Created a working version here off of your codepen here... https://codepen.io/SEAjamieD/pen/bvggOw?editors=0110

Probably not ideal to add and remove classes so quickly like that but it works. You might think about moving the animations into a keyframe. Hope this helps!

Upvotes: 0

Related Questions