What is the best way to modify CSS animation property without causing any disruptions?

Could you help me with modifying this CSS animation? I want to adjust the animation-iteration-count to 1 only when a certain property, status, is added to the element. Currently, the animation is not working as expected.

For example:

setTimeout(() => {
  const e = document.querySelector('div')
  e.classList.add('status')
}, 5000)
div {
  position: relative;
}

div::before {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    border-bottom: 2px solid #00849b;
    animation-name: border-animation;
    animation-duration: 1s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-fill-mode: forwards;
}

div.status::before {
    animation-name: border-animation;
    animation-duration: 1s;
    animation-timing-function: linear;
    animation-iteration-count: 1;
    animation-fill-mode: forwards;
}

@keyframes border-animation {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}
<div>Hiiiiiiiii!</div>

Answer №1

Here is a demonstration of how you can ensure that the animation completes before updating the animation-iteration-count:

  1. I have introduced a CSS variable in the :root selector to store the iteration count, allowing us to target it with JavaScript as pseudo elements cannot be directly targeted.
  2. I have provided two methods for adding the status class to the element - either by clicking on it or utilizing the original setTimeout function with a non-round second value (e.g., 1000, 2000, 3000, etc.).
  3. The code includes detailed comments describing each step and action taken.

// Selects the div element.
const e = document.querySelector('div');
// Variable to track the iteration count, updated upon animationiteration event.
let iterationCount = 0;

// Function to monitor the iteration count.
function check_iteration_count() {
  // Listen for the animationiteration event on constant e element.
  e.addEventListener('animationiteration', () => {
    // Increments the iteration count after the current iteration completes.
    iterationCount++;
    // Once this function initiates the increment, reaching 1 signifies completion of one iteration.
    if (iterationCount === 1) {
      // Changes the CSS variable to the desired iteration count of 1 to halt the animation.
      document.documentElement.style.setProperty('--iteration-count', '1');
    }
  });
}

// When clicked.
e.addEventListener('click', (event) => {
  // Adds the status class to the div upon click.
  event.target.classList.add('status');
  // Executes the function to update the iterator.
  check_iteration_count();
});

// Original timeout function. Utilizes a non-exact second value.
setTimeout(() => {
  // Adds the status class to the div after timeout.
  e.classList.add('status');
  // Calls the function to update the iterator.
  check_iteration_count();
}, 5100);
:root {
  --iteration-count: infinite;
}

div {
  position: relative;
}

div::before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  border-bottom: 2px solid #00849b;
  transition: border-bottom .3s ease;
  animation-name: border-animation;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-iteration-count: var(--iteration-count);
  animation-fill-mode: forwards;
}


/* Highlighting the addition of status class */

div.status::before {
  border-bottom-color: red;
}

div.status::before {
  animation-name: border-animation;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-iteration-count: var(--iteration-count);
  animation-fill-mode: forwards;
}

@keyframes border-animation {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}
<div>Hello!</div>

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

"Drag and drop elements that automatically snap to a grid and move with

I'm trying to create a small, square div that follows the mouse cursor, but I want it to snap to a 3x3 pixel grid. Here is what I have so far: $(document).mousemove(function(e) { window.x = e.pageX; window.y = e.pageY; if(window.x % 9 === 0 ){ ...

Adjust the input value with CSS when hovering

Whenever I click on a button, the name of that button is displayed on the site. However, I am looking to change this button name when hovering over it but I am not sure how to do it. echo '<form id="button" method="POST" >&ap ...

`Is it possible to animate the rotation of an image within an input control?`

After coming across this helpful answer, I successfully added a rotating GIF image as an icon inside an INPUT control on its right side. Simply applying the "busy" class to my control did the trick, and now it looks like it's in progress. input.busy { ...

Determining the Number of Sub-Menu Items Using jQuery without Reliance on CSS Classes

I've scoured the depths of Google and SO in search of answers, but nothing quite fits the bill. My mission is to create a submenu without using classes, adding a style attribute to each individual <li> within the sub <ul> that sets a min- ...

Tips for expanding a script that relocates a logo into a navigation consisting of several unordered lists

I recently implemented a jQuery script to center a logo within my main navigation bar only when the screen width is above 980 pixels. It was working perfectly fine with a single unordered list, but as soon as I added more unordered lists within the nav, it ...

Is the in-app browser of WeChat able to support self-signed HTTPS URLs?

My local WAMP server hosts a web application with self-signed SSL enabled, resulting in the following app URL: https://myipaddress:port/demoapp/index.html However, when I send this URL via WeChat chat and click on it, only a blank page is displayed. Stra ...

Determining the top element displayed in a div: A guide

Looking for an answer on how to determine the top visible element while scrolling? You may find some insights in this post: (Check if element is visible after scrolling). My scenario is slightly different - I have a scrollable div containing multiple ele ...

mentioning a JSON key that includes a period

How can I reference a specific field from the JSON data in Angular? { "elements": [ { "LCSSEASON.IDA2A2": "351453", "LCSSEASON.BRANCHIDITERATIONINFO": "335697" }, { "LCSSEASON.IDA2A2": "353995", "LCSSEASON.BRANCHIDITER ...

Troubles with Sizing in Twitter Bootstrap Modal

One issue I have encountered with my application is the varying widths of modals. Setting the width inline works well, but when the window is compressed it can cause part of the modal to be off screen, rendering it useless at smaller resolutions such as th ...

Adding Data to a Database Using Ajax with PHP

I am trying to use Ajax to insert data into a database, but I keep encountering this error: Uncaught ReferenceError: insertData is not defined at HTMLInputElement.onclick (Modal.php:105) Error screenshot: The HTML and JS for this functionality are in ...

Text in React Native exceeding one line is causing it to extend beyond the screen boundaries

I am having trouble displaying the last messages in my simple contact list as the text is getting cut off the screen. Below is the code I am using: (the readableTimestamp should be positioned behind the text.) View style={{ fontSize: 16, backgro ...

Is there a distinction between the values 'normal' and 'stretch' in the CSS property known as 'align-content'?

When it comes to the CSS declaration 'align-content', the default value is 'normal'. But, there is also another option: 'stretch'. I have been having a hard time figuring out if there is any actual difference between the two. ...

What is the best way to retrieve the dates for the current month as well as the following month

I have a php script that I need to modify in order to display the current month and the next month's dates using PHP. Below are the functions I am currently using for this purpose. html/php code (functions for current month and next month): <!-- D ...

The Flask server push appears to be functioning correctly, yet the EventSource.onmessage event is not triggering as expected

My implementation includes a route /stream that is designed to push the string 'test' every second. Upon accessing this URL (localhost:12346/stream) on Chrome, I observed that it opens a blank page and adds "test" to the page every second. This ...

Shift the plus-minus icon on the bootstrap accordion all the way to the right side

I'm struggling to adjust the position of the plus-minus icon on a Bootstrap accordion to the far right, but my current code isn't producing the desired result. Here's the CSS snippet: .mb-0 > a:before { float: right !important; ...

How about displaying the Ajax response as an image?

I'm working on a script that pulls an image link, which seems to be functioning correctly. However, I am struggling with how to display the link as an image. Can someone please assist me with this? <script src="//ajax.googleapis.com/ajax/li ...

Ways to eliminate the .html extension when someone accesses your static website

My current setup involves a static website being served by nginx. For example, when visiting www.mydomain.com, it displays as www.mydomain.com/index.html. Is there a way to avoid the trailing .html and have www.mydomain.com/index displayed instead? I&ap ...

Align list items in the center horizontally regardless of the width

I have created this container element: export const Container = styled.section<ContainerProps>` display: flex; justify-content: center; `; The current setup is vertically centering three list items within the container. However, I am now looking ...

Floating and scrolling navigation bar not functioning properly in bootstrap framework

I've been dabbling in coding for a while now, practicing at my current job. I managed to create a floating and scrolling navigation bar on the right side of my website using bootstrap. However, after taking a 3-week break and returning to my site, I n ...

Utilizing commas in JavaScript

Hi everyone, I'm having an issue with printing the message "Invalid password, Must Contain:". The problem I'm facing is that when I write the code in JavaScript, the comma is being interpreted as an operator instead of a regular English comma. Th ...