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

The alignment of the background images is off

I am attempting to give a container a background image and then create two div tags using the col-md-6 classes from Bootstrap. The main div's background image is of grass texture, while the two inner divs have a skeleton of a football court as their b ...

How can I retrieve the content from an iframe whenever its state is altered using jQuery?

I am currently working on a project where I need to extract the content from a hidden iframe and display it as HTML in a div every time the iframe changes its loading state. The goal is for it to appear as if the page is being redirected and downloading it ...

Issue with Sass @use failing to load partial

I'm currently facing an issue while trying to import a sass partial called _variables.scss into my main stylesheet named global.scss. Every time I compile the sass code, I encounter the following error message: Error: Undefined variable. Here is the ...

Examples of how to specify a child class in CSS

Presented here is the following structure: <article class="media media--small 48"> <a href="#"> <img src="" class="media__img" alt=""> <i class="s s--plus"></i></a> <div class="media__body"> < ...

Expanding the `div` element to visually occupy the entire vertical space

I'm facing a design challenge with my webpage layout. I have a fixed header and footer, but I need the content section to dynamically adjust its height between the two. The goal is to fill the remaining vertical space with a background-image in the co ...

Locate all elements containing a specific text string

In an attempt to clean up html-elements, I am searching for specific text strings within 2376 html-documents. The documents have varying doctype standards, with some lacking a doctype altogether (which may not be relevant). I am specifically looking for t ...

Ways to animate a div downward when the mouse hovers over it using jQuery

Looking to create a sleek <div> that smoothly descends when a user hovers over it. I think this involves jQuery, a skill I have not mastered yet. Appreciate any assistance you can provide! ...

If you click outside of a Div element, the Div element will close

I am looking for a way to implement a function that will hide a specific div when I click outside of its area. The div is initially set to Position: none and can be made visible using the following function: Div Element: <div id="TopBarBoxInfo1" oncli ...

Evaluating CSS Specificity

Is there a recommended approach for automatically testing css selectors? I am in the process of developing a SCSS framework and I want to integrate automated tests. Specifically, I aim to verify that the css selectors are functioning correctly. For examp ...

What could be causing mobile phones to overlook my CSS media query?

My CSS includes 3 media queries that function properly when I resize the browser, but fail to work when using the responsive design tool in the inspector ("toggle device mode") and on mobile devices. Snippet of my CSS code : @media screen and (max-width: ...

How can screen readers be alerted about freshly loaded content through ajax?

Whenever a user clicks on a button, I want to add more content to the page. The new content will be visually clear, but how can I ensure that screen readers can easily access it? I've come across two best practices that suggest additional steps may b ...

What are some effective strategies for preventing CSS duplication?

What is the best way to prevent repeating CSS code like this: div#logo div:nth-child(1) div { width: 30%; height: 30%; background-color: white; } div#logo div:nth-child(3) div { width: 30%; height: 30%; background-color: white; ...

What is the process for inserting an image into a table using el-table and el-table-column components in Vue.js while utilizing ui-elements?

I'm new to Vue.js and successfully built a basic table using the ui-element. The el-table element was utilized for constructing the table, with columns displayed using el-table-column and prop (see code below). Now, I want to incorporate images/avatar ...

The alignment of bullets in CSS property list-style-position is off

I'm encountering an issue with aligning the list items. I've been using the CSS property list-style-position: inside; Typically, the bullet points appear outside of the text, like this: https://i.stack.imgur.com/LcVB0.png This doesn't seem ...

Issue with unordered list in the footer overlapping other elements

I've been struggling to resolve an issue with my footer for quite some time now. The problem seems to be arising from my unordered list being set to float right, causing it to overflow the parent div. Could someone please shed light on what I might b ...

Having difficulty changing the visibility of a div with Javascript

I've developed a piece of vanilla JavaScript to toggle the visibility of certain divs based on the field value within them. However, I'm encountering an issue where trying to unhide these divs using getElementById is resulting in null values. D ...

Ways to make ionic slides adhere to column width

I've been immersing myself in learning the latest versions of AngularJS and Ionic through practical application. I am currently working on a page that uses ionic rows and columns to display JSON data. The layout includes a 50/50 column setup, with a t ...

Is there a way to handle specific email format designs with PHP?

When trying to send an email with specific shipping information and tracking numbers, the formatting appears strange. Here is the desired format: Dear xyz , Per your request, this email is to no ...

Display information from a .js file onto an HTML webpage

I'm completely new to the world of server-side development and I'm attempting to navigate it on my own. Currently, I have a server written in JavaScript using Express and I'm trying to display some content on my HTML page that was sent from ...

Issues with the OnChange function not properly functioning in duplicate input fields

I've designed a form that allows for adding or deleting rows, effectively cloning input fields. One of the input fields utilizes Jquery Ajax to retrieve its value. However, upon adding an extra row by cloning the parent row to generate a child row, th ...