What is causing the issue with my CSS keyframe animation not functioning correctly when using `animation-direction: reverse`?

Exploring the use of animation-direction: reverse to streamline my CSS keyframe animation process. An interesting scenario arises when a container div is clicked, toggling an "active" class using jQuery to trigger the animation in either forward or backward direction based on the class state. Both animations are essentially the same, with only the order of keyframes reversed. Initially, I expected that setting animation-direction: reverse would simplify this by allowing one animation to be reversed for the other, but it doesn't seem to function as anticipated.

To view the codepen example without utilizing animation-direction: reverse, click the link below: https://codepen.io/soultrust/pen/gogKjN

The current markup and Sass CSS code snippet demonstrate how the animation works without reversing.

<div class="container">
  <div class="line"></div>
</div>

 

$width-height: 100px;
$duration: 1s;
$line-width: 10%;
$animation-distance: $width-height * .45;

@keyframes line-in {
  0% { transform: translateY(-$animation-distance); }
  50% { transform: translateY(0); }
  100% { transform: rotate(-135deg); }
}

@keyframes line-out {
  0% { transform: rotate(-135deg); }
  50% { transform: translateY(0); }
  100% { transform: translateY(-$animation-distance); }
}

.container {
  margin: 10rem auto 0;
  width: $width-height;
  height: $width-height;
  position: relative;
  border: 1px solid black;

  &.active {
    .line {
      animation-name: line-in;
      animation-direction: normal;
    }
  }
}

.line {
  width: 100%;
  height: $line-width;
  position: absolute;
  top: 45%;
  background-color: orange;
  animation-direction: normal;
  animation-name: line-out;
  animation-duration: $duration;
  animation-fill-mode: forwards;
}

Upon changing the "active" animation as below, both directions of animations cease functioning:

&.active {
  .line {
    animation-name: line-out;
    animation-direction: reverse;
  }
}

It seems the issue lies in using the same animation, as manually setting animation-direction: reverse paired with animation-name: line-in effectively triggers the reversal of the line-in animation.

Answer №1

Impressive query you have made! It seems like you have grasped that animation-direction: reverse; does indeed function as expected. You were very close to unraveling this unique quirk of CSS on your own.

There are a few additional rules worth noting:

  • When removing or replacing a CSS animation, it will always start from 0%.
  • If you set reverse without changing the actual animation, it will continue from its current percentage.

So when you triggered the line-out animation by clicking the element:

  • The animation started from 0%.
  • It played in the direction you specified.

However, if you only change the animation direction:

  • The animation will continue from whatever percentage it was at, for example, 100%.

You can explore various methods to restart the animation, where you might notice it playing in reverse upon recreation of the element.

var clickFunc =function(e) {    
      //toggle the state
      $(this).toggleClass("active");
      //reset the animatino state by cloning and replacing the element.
      var newone = this.cloneNode(true);
      this.parentNode.replaceChild(newone, this);
      // reapply click handler to the cloned element
      $(newone).click(clickFunc)   
}


$(function() {
  $(".question").click(function() {
    $(this).toggleClass("active");
  });
  
    $(".answer").click(clickFunc);

  $(".restart").click(function() {
    $(".line").each(function() {
      var newone = this.cloneNode(true);
      this.parentNode.replaceChild(newone, this);
    });
  });
});
@keyframes line-in {
  0% {
    transform: translateY(-45px);
  }
  50% {
    transform: translateY(0);
  }
  100% {
    transform: rotate(-135deg);
  }
}
@keyframes line-out {
  0% {
    transform: rotate(-135deg);
  }
  50% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-45px);
  }
}
.line {
  width: 100%;
  height: 10%;
  position: absolute;
  top: 45%;
  background-color: orange;
  animation-direction: normal;
  animation-name: line-in;
  animation-duration: 1s;
  animation-fill-mode: forwards;
}

.container {
  margin: 1rem auto 0;
  width: 100px;
  height: 100px;
  position: relative;
  border: 1px solid black;
}
.container.reverse .line {
  animation-name: line-in;
  animation-direction: reverse;
}
.container.active .line {
  animation-name: line-in;
  animation-direction: reverse;
}
.container.active.reverse .line {
  animation-name: line-in;
  animation-direction: normal;
}

.container.out.active .line {
  animation-name: line-out;
  animation-direction: normal;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="restart">reset animation state</button><br>
in -out
<div class="container question out">
  <div class="line"></div>
</div>

active reversed
<div class="container question">
  <div class="line"></div>
</div>

<br>

workaround
<div class="container answer reverse">
  <div class="line"></div>
</div>

To debug this behavior, you can inspect the animation states using your browser's web dev tools: https://i.stack.imgur.com/TFZLT.png

In terms of your refactor: I recommend using multiple animations in different directions rather than relying on JavaScript tricks to restart or reverse an animation.

Depending on the complexity of your animation, consider utilizing CSS transitions instead of keyframes. This way, you won't need to worry about reversing or resetting the animation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Additional <li> elements are created in Internet Explorer versions 8 and 9

Currently in the process of setting up a new website/landing page. Upon heading to the right column at the bottom (where the pictures are located), you will notice <li> elements containing pictures within containers. The only issue that arises is whe ...

Implementing a line break within a JavaScript function specifically designed for formatting images

As I am not a javascript developer, the code I have been given for debugging is somewhat challenging. The issue at hand involves an iOS module where a .js CSS file has been set up and images are loading improperly, resulting in the need for horizontal scro ...

Unexpected results from CSS nth-child selector

Creating a dynamic table and updating its cell values accordingly while handling asynchronous returns brings about some challenges. The number of columns can vary, but the rows remain constant within this section of the table (7 rows). When trying to upda ...

Reduce the length of selection choices in the dropdown menu of WebForms

In my WebForms project, I have created a drop-down list by binding a list of data with 'Title' and 'Id' to it. Ddltitlelist.DataSource = submissionTitleList; Ddltitlelist.DataTextField = "Submission_Title"; Ddltitlelist.DataValueField ...

Display the scrollbar on a flexbox container instead of the entire browser window

I'm curious about how to implement a scroll-bar on a div using flexbox CSS. To better illustrate the issue, I've provided an example below: * { box-sizing: border-box; } .flex-display { display: flex; align-items: stretch; height: 100 ...

Adding an HTML arrow icon within a button

As I work on creating an HTML email, my aim is to incorporate a right arrow onto an HTML button. To achieve this, I have opted to utilize a special character and apply the transform-rotate property. However, I am facing an issue where the text and arrow a ...

Retrieve base64 encoded data from several content attributes

Is there a way to optimize the use of base64 data in CSS by defining it once and referencing it in multiple content properties? div#my_id1 { content: url(data:image/png;base64,...); } div#my_id2 { content: url(data:image/png;base64,...); } Using ...

Issue with image display in Chrome caused by Flexbox styling

I recently set up a flexbox for my website, but I'm encountering an issue in Chrome. When the viewport is smaller than the width of two images, the entire site zooms out and everything gets distorted. However, this problem doesn't occur in Firefo ...

Can AJAX Delete requests be executed without using jQuery?

Is it possible to use AJAX delete request without using jQuery? My JSON object at localhost:8000 appears like this: { "Students":[{"Name":"Kaushal","Roll_No":30,"Percentage":94.5}, {"Name":"Rohit","Roll_No":31,"Percentage":93.5}, {"Name":"Kumar ...

Find the current location of the scroll bar on the view port

Currently, I am utilizing the Addazle React grid for my project. However, I need to incorporate endless scrolling functionality which is not already included in this grid system. Thus, I am tasked with devising my own solution for this issue. To successful ...

How can I generate a hyperlink for a specific directory on Github Pages?

If I have a repository with one file and one folder, as listed below: index.html folder The folder contains another file named: work.html My goal is to access the folder website using only the link: username.github.io/repositoryname/folder Instead ...

The menu is about to receive some custom styling

I have come across a webpage where I need to make some modifications, but I am unable to locate the script responsible for applying the inline style. This issue only seems to be occurring on the mobile version with the dropdown menu. <div class="is-dri ...

When hovering over nav bar links, shadows are not displayed

When hovering over the navbar links, I am able to change their color but a shadow at the bottom is missing. Is there a way to add a shadow at the bottom like it had before when not hovered? Visit this link for more information ...

The left border is failing to appear on the Td element

When attempting to add border styling to td elements, the left border is not displaying correctly. This issue seems to vary across different browsers. Here is the HTML code: <table class="table-bordered"> <thead> <tr> ...

Can I use javascript/jquery to alter the direction of text in each line?

Looking for assistance with changing text direction on each new line. For instance: text left-to-right text right-to-left text left-to-right text right-to-left... etc. I would like the text direction to change with each word-wrap: break-word. Any help w ...

Error with adaptable menu

I am attempting to develop a responsive menu similar to the Bootstrap nav bar using only CSS. I have managed to get the functionality working, but the positioning of the menu grabber is incorrect and I'm unsure how to correct it. The grabber should al ...

What is the best way to position a button to the right side of the screen?

Is there a way to align a button to the right of a page? I attempted using text-align: right; and align-content: right; In addition, I want the button to utilize display: flex; #hideShow { display: flex; text-align: right; align-content: right; ...

Create a Bootstrap multi-bar component for visually displaying the daytime information

I am looking to create a horizontal bar with multiple intervals. Here is what I have tried so far: <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"& ...

A stylish Bootstrap list group featuring large Font Awesome icons

I am working with a Bootstrap 5 List Group element on my webpage. To enhance its visual appeal, I want to include oversized Font Awesome icons. After some styling and using a span tag, I managed to add the icon successfully. However, the issue I am facing ...

The background on my modal remains unchanged

I have integrated a modal using Iframe for user login/registration on my website. Here is the HTML code: <div class="modal" id="ays-popin-connexion" aria-hidden="true"> <div class="modal-body" aria-hidden="true"> <iframe src=" ...