Search code examples
javascriptcsscss-animationscss-transitionscss-transforms

How can I create a button that always rotates in the same direction when clicked in CSS?


my goal is to make a flippable card in css that always rotates around the x-Axis when clicked, but I can't figure out how to make the card rotate in the same direction everytime. What I got is only to make the card rotate 180° when clicked the first time, but it will rotate back in the opposite direction when clicked again, which is not the kind of effect I wanted to achieve. I found this solution but it uses JQuery and feels very hacky, is there a more straight-forward solution maybe even in pure CSS?

Any help would be appreciated thanks in advance.

A little code example of what I achieved so far:

function flip(id) {
  document.getElementById(id).querySelector(".flip-content").classList.toggle("flipped");
}
.flip-card {
    background: transparent;
    perspective: 1000px;
    width: 200px;
    height: 200px;
    transition: transform 0.3s;
    transform: scale(90%);
}
.flip-content {
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: all 0.6s;
    box-shadow: 0 20px 32px 0 rgba(0, 0, 0, 0.2);
}
.flip-content.flipped {
    transform: rotateX(180deg);
    box-shadow: 0 -20px 32px 0 rgba(0, 0, 0, 0.2);
}
<div id="flip" class="flip-card" onclick="flip('flip')">
  <div class="flip-content">
  </div>
</div>


Solution

  • You could run the transform directly onto the element with javascript without toggling class, like so:

    let rot = 0;
    
    function flip(id) {
      rot += 180;
      const flipContent = document.getElementById(id).querySelector(".flip-content");
      flipContent.style.transform = `rotateX(${rot}deg)`;
      flipContent.style['box-shadow'] = (rot % 360 === 0) ? `0 20px 32px 0 rgba(0, 0, 0, 0.2)` : `0 -20px 32px 0 rgba(0, 0, 0, 0.2)`;
    }
    .flip-card {
        background: transparent;
        perspective: 1000px;
        width: 200px;
        height: 200px;
        transition: transform 0.3s;
        transform: scale(90%);
    }
    .flip-content {
        width: 100%;
        height: 100%;
        transform-style: preserve-3d;
        transition: all 0.6s;
        box-shadow: 0 20px 32px 0 rgba(0, 0, 0, 0.2);
    }
    .flip-content.flipped {
        transform: rotateX(180deg);
        box-shadow: 0 -20px 32px 0 rgba(0, 0, 0, 0.2);
    }
    <div id="flip" class="flip-card" onclick="flip('flip')">
      <div class="flip-content">
      </div>
    </div>