Search code examples
htmlcsswebcss-animationscss-transforms

Preserve CSS transform property after removing the class


Is it possible to preserve a CSS property (including variables) after removing a class that modifies them ?

The problem is in the code below. I want to preserve the transform property of the cyan box after removing the class animation-slide-to-left that slides the box to the left. That is because when removing that animation-slide-to-left and adding the class animation-slide-to-right class, I want that new animation to start from where the old one ended.

But the problem is when removing animation-slide-to-left the transform property resets and becomes equal to Its old value before adding that class.

Note: I don't want to hard code the transform property at 0%, because there are a lot of animations, and I am searching for a way that automatically solve the problem without JAVASCRIPT.

(expand the snippet result to full page too see the example)

const box = document.querySelector (".animated");

function leftclicked (){
  box.classList.remove ("animation-slide-to-right");
  box.classList.add ("animation-slide-to-left");
}

function rightclicked (){
  box.classList.remove ("animation-slide-to-left");
  box.classList.add ("animation-slide-to-right");
}
.center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.animated {
  animation-duration: 0.5s;
	animation-delay: 0s;
	animation-iteration-count: 1;
	animation-direction: normal;
	animation-timing-function: ease-out;
	animation-fill-mode: forwards;
}

.animation-slide-to-left {
	animation-name: slide-to-left;
}

.animation-slide-to-right {
	animation-name: slide-to-right;
}


@keyframes slide-to-left {
  100%{
    transform: translate(-150%, -50%);
  }
}

@keyframes slide-to-right {
  100%{
    transform: translate(50%, -50%);
  }
}
<div class="center" style="width:300px; height: 300px; background-color: red;">

  <div class="center animated" style="width: 50%; height: 50%; background-color:cyan;">
  </div>
  
  <button style="float:left;" onclick="leftclicked()">LEFT</button>
  <button style="float:right;" onclick="rightclicked()">RIGHT</button>
  
</div>


Solution

  • You can set the starting position for each time you click on the buttons LEFT and RIGHT in the CSS keyframes, so that when the button is on the left side and click on the RIGHT button, it first sets the position to the left side (0%) before it animates to the right (100%) and vice-versa. This way it doesn't reset back to the center when clicking the buttons.

    const box = document.querySelector (".animated");
    
    function leftclicked (){
      box.style.transform = 'translate(50%, -50%)';
      box.classList.remove ("animation-slide-to-right");
      box.classList.add ("animation-slide-to-left");
    }
    
    function rightclicked (){
      box.style.transform = 'translate(-150%, -50%)';
      box.classList.remove ("animation-slide-to-left");
      box.classList.add ("animation-slide-to-right");
    }
    .center {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    
    .animated {
      animation-duration: 0.5s;
    	animation-delay: 0s;
    	animation-iteration-count: 1;
    	animation-direction: normal;
    	animation-timing-function: ease-out;
    	animation-fill-mode: forwards;
    }
    
    .animation-slide-to-left {
    	animation-name: slide-to-left;
    }
    
    .animation-slide-to-right {
    	animation-name: slide-to-right;
    }
    
    
    @keyframes slide-to-left {
      100%{
        transform: translate(-150%, -50%);
      }
    }
    
    @keyframes slide-to-right {
      100%{
        transform: translate(50%, -50%);
      }
    }
    <div class="center" style="width:300px; height: 300px; background-color: red;">
    
      <div class="center animated" style="width: 50%; height: 50%; background-color:cyan;">
      </div>
      
      <button style="float:left;" onclick="leftclicked()">LEFT</button>
      <button style="float:right;" onclick="rightclicked()">RIGHT</button>
      
    </div>