Restart CSS Animation (using CSS to trigger a reflow)

by Michael Scharnagl

This article has been updated the last time on January 3, 2016 and the given information may be not accurate anymore. Feel free to contact me on twitter to get more details.

Lately, I wanted to run an animation on page load and the same animation again on :hover. After some debugging I figured out this doesn’t work as expected.

Here is the simplified CSS showing my problem:

/* a simple animation */
@keyframes test {
  0% {background: red;}
  100% {background: blue;}
}

div {
 animation: test 4s ease-out;
}

/* run the animation again on hover, won't work this way */
div:hover {
 animation: test 4s ease-out;
}

After a quick search, I came across this article on css-tricks.com where Chris and Oli show techniques to solve this problem. The conclusion is that you can either use JavaScript or as Oli Studholme researched, use an identical @keyframes animation with a different name for :hover. As the article and research are quite old (in terms of web development 4 years is actually really old) I started a new jsbin and tried to find a different solution. After some trial and error, I found another way using CSS.

So here it is:

/* a simple animation */
@keyframes test {
  0% {background: red;}
  100% {background: blue;}
}

/* Trigger reflow */
@-webkit-keyframes test1 {
  to {width: auto;}
}

div {
 animation: test 4s ease-out;
}

/* run the animation again and again on hover, check! */
div:hover {
 animation-name: test1;
}

The trick is to add a second animation, which animates the width (can also be auto as you can see, so the width won’t change actually) to trigger reflow, to :hover. Try it out on jsbin.

It’s working in Firefox, Opera, Chrome and IE10 upwards.

Any question? Contact me.

One thought on “Restart CSS Animation (using CSS to trigger a reflow)

  1. Brian says:

    That doesn’t seem to retrigger the animation until the hover ends though.

    In Firefox you can get the animation to restart on hover just by changing the div:hover declaration to:

    animation-name: test, test;

    Unfortunately it won’t work in Chrome yet because it conflates multiple animations with the same name.

Michael Scharnagl

Portrait Michael Scharnagl

Follow me: @justmarkup

Subscribe to RSS: /feed

A freelance front-end developer focusing on HTML5, CSS, progressive enhancement and web performance.