Search code examples
htmlcssgoogle-chromecss-transitionscss-transforms

Can't select inputs after TransformY on chrome for a "card flipping" effect


I have a "card" design in which I have an div with two children, a "front" and a "back". A "card flipping" effect is achieved by applying a rotateY(180deg) transform to the card, hiding the back-face.

I've noticed a few differences between chrome and firefox. On firefox, the animation is smooth, on chrome, there's a flash of white. But most importantly, an input element on the "back" face of the card is not clickable in Chrome.

You can see the effect in each browser in these gifs:

a card in chrome a card in firefox

Any ideas on what is going on?

Code available at this pen: https://codepen.io/elbasti/pen/poJjLmP

function flipCard() {
  var element = document.getElementById("flipper-container");
  element.classList.toggle("flipper--flipped");
}
.flipper {
  perspective: 1000px;
  width: 200px;
  height: 200px;
  flex: 0 1 auto;
}

.card {
  height: 200px;
  width: 200px;
  transition: transform 1s;
  transform-style: preserve-3d;
  padding: 0px;
  backface-visibility: hidden;
}

.card__face {
  box-sizing: border-box;
  border-radius: 12px;
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  padding: 20px;
  backface-visibility: hidden;
}

.card__face--back {
  background-color: #9e0495;
  position: relative;
  height: 100%;
  color: white;
  transform: rotateY(180deg);
}

.card__face--front {
  background: gray;
}

.flipper.flipper--flipped .card {
  transform: rotateY(180deg);
  transition: transform 0.5s;
}
<div id="flipper-container" class="flipper">
  <div class="card">
    <div class="card__face card__face--back">
      <p>I am the back</p>
      <input type="text" placeholder="Back input">
      <p>The back one doeesn't work in chrome :(</p>
    </div>

    <div class="card__face card__face--front">
      <p>I am the front</p>
      <input type="text" placeholder="Front input">
      <p>The front input works.</p>
    </div>
  </div>
</div>

<button id="toggle-flip" onclick="flipCard()">Click me</button>


Solution

  • It seems, that .card overlaps the back after rotation.

    Maybe you could rotate not .card but .card__face--front and .card__face--back. I made some modifications in snippet.

    function flipCard() {
      var element = document.getElementById("flipper-container");
      element.classList.toggle("flipper--flipped");
    }
    .flipper {
      perspective: 1000px;
      width: 200px;
      height: 200px;
      flex: 0 1 auto;
    }
    
    .card {
      height: 200px;
      width: 200px;
      transition: transform 1s;
      transform-style: preserve-3d;
      padding: 0px;
      backface-visibility: hidden;
    }
    
    .card__face {
      box-sizing: border-box;
      border-radius: 12px;
      position: absolute;
      height: 100%;
      width: 100%;
      top: 0;
      left: 0;
      padding: 20px;
      backface-visibility: hidden;
    }
    
    .card__face--back {
      background-color: #9e0495;
      position: absolute;
      height: 100%;
      color: white;
      transform: rotateY(180deg);
      transition: transform 0.5s;
    }
    
    .card__face--front {
      background: gray;
      transition: transform 0.5s;
    }
    
    .flipper.flipper--flipped .card__face--front {
      transform: rotateY(-180deg);
      transition: transform 0.5s;
    }
    
    .flipper.flipper--flipped .card__face--back {
      transform: rotateY(0deg);
      transition: transform 0.5s;
    }
    <div id="flipper-container" class="flipper">
      <div class="card">
        <div class="card__face card__face--back">
          <p>I am the back</p>
          <input type="text" placeholder="Back input">
          <p>The back one doeesn't work in chrome :(</p>
        </div>
    
        <div class="card__face card__face--front">
          <p>I am the front</p>
          <input type="text" placeholder="Front input">
          <p>The front input works.</p>
        </div>
      </div>
    </div>
    
    <button id="toggle-flip" onclick="flipCard()">Click me</button>