Run CSS3 animation only once (at page loading)

CssCss Animations

Css Problem Overview


I'm making a simple landing page driven by CSS3. To make it look awesome there's an <a> plopping up:

@keyframes splash {
	from {
		opacity: 0;
		transform: scale(0, 0);
	}
	50% {
		opacity: 1;
		transform: scale(1.1, 1.1);
	}
	to {
		transform: scale(1, 1);
	}
}

And to make it even more awesome I added a hover animation:

@keyframes hover {
	from {
		transform: scale(1, 1);
	}
	to {
		transform: scale(1.1, 1.1);
	}
}

But there comes the problem! I assigned the animations like this:

a {
	/* Some basic styling here */
	
	animation: splash 1s normal forwards ease-in-out;
}
a:hover {
	animation: hover 1s infinite alternate ease-in-out;
}

Everything works just fine: The <a> splashes into the users face and has a nice vibration when he hovers it. Bit as soon as the user blurs the <a> the smooth stuff ends abruptly and the <a> repeats the splash-animation. (Which is logical to me, but I don't want it to) Is there some way to solve this problem without some JavaScript Class Jiggery Pokery?

Css Solutions


Solution 1 - Css

After hours of googling: No, it's not possible without JavaScript. The animation-iteration-count: 1; is internally saved in the animation shothand attribute, which gets resetted and overwritten on :hover. When we blur the <a> and release the :hover the old class reapplies and therefore again resets the animation attribute.

There sadly is no way to save a certain attribute states across element states.

You'll have to use JavaScript.

Solution 2 - Css

If I understand correctly that you want to play the animation on A only once youu have to add

animation-iteration-count: 1

to the style for the a.

Solution 3 - Css

It can be done with a little bit of extra overhead.

Simply wrap your link in a div, and separate the animation.

the html ..

<div class="animateOnce">
    <a class="animateOnHover">me!</a>
</div>

.. and the css ..

.animateOnce {
    animation: splash 1s normal forwards ease-in-out;
}

.animateOnHover:hover {
    animation: hover 1s infinite alternate ease-in-out;
}

Solution 4 - Css

I just got this working on Firefox and Chrome. You just add/remove the below class accordingly to your needs.

.animateOnce {
  -webkit-animation: NAME-OF-YOUR-ANIMATION 0.5s normal forwards; 
  -moz-animation:    NAME-OF-YOUR-ANIMATION 0.5s normal forwards;
  -o-animation:      NAME-OF-YOUR-ANIMATION 0.5s normal forwards;
}

Solution 5 - Css

An easy solution to solve this problem is by just adding more seconds to the animation in a:hover and taking advantage of the transitions in @keyframes

a:hover {
        animation: hover 200s infinite alternate ease-in-out;
    }

Just make the progression of @keyframes go faster by using percentages.

@keyframes hover {
    0% {
        transform: scale(1, 1);
    }
    1% {
        transform: scale(1.1, 1.1);
    }
    100% {
        transform: scale(1.1, 1.1);
    }
}

200 seconds or 300 seconds in the animation is more than enough to make sure the animation doesn't restart. A normal person won't last more than a few seconds hovering an image.

Solution 6 - Css

Just use

animation: hover 1s ease-in-out forwards;

Solution 7 - Css

Impossible in CSS only, you need a javascript workaround. As already explained by some here, the animation-iteration-count property is reset on a :hover. The best is to do everything in javascript, but for reasons of ease of customization of the code you may want to keep the possibility of doing something in CSS.

So, in JS :

// adding a class to the html tag, during the animation time 
const startPage = (() => {
  const html = document.documentElement,
        s = 'start-map'
  html.classList.add(s)
  window.addEventListener('load', function() {
    setTimeout(() => {
      html.classList.remove(s)
    }, 1500) // the time must be at least equal to the duration of the CSS animation (personally I put a little more).
  })
})()

And for the CSS:

/* the presence of the `.start` class conditions the animation */
.start .leaflet-marker-pane {
    animation: animDrop 1s ease;
}

Solution 8 - Css

The following code without "iteration-count: 1" was resulting in all line items pulsing after entering, until the last item loaded, even though 'pulse was not being used.

<li class="animated slideInLeft delay-1s animation-iteration-count: 1"><i class="fa fa-credit-card" aria-hidden="true"></i> 1111</li>

					
<li class="animated slideInRight delay-1-5s animation-iteration-count: 1"><i class="fa fa-university" aria-hidden="true"></i> 222222</li>
					
<li class="animated lightSpeedIn delay-2s animation-iteration-count: 1"><i class="fa fa-industry" aria-hidden="true"></i> aaaaaa</li>
					
<li class="animated slideInLeft delay-2-5s animation-iteration-count: 1"><i class="fa fa-key" aria-hidden="true"></i> bbbbb</li>
					
<li class="animated slideInRight delay-3s animation-iteration-count: 1"><i class="fa fa-thumbs-up" aria-hidden="true"></i> ccccc</li>

Solution 9 - Css

So i just found a solution for that: In the hover animation do this:

animation: hover 1s infinite alternate ease-in-out,splash 1;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbuschtoensView Question on Stackoverflow
Solution 1 - CssbuschtoensView Answer on Stackoverflow
Solution 2 - CssStrelokView Answer on Stackoverflow
Solution 3 - CssButsuriView Answer on Stackoverflow
Solution 4 - CssRicardusView Answer on Stackoverflow
Solution 5 - CssGassView Answer on Stackoverflow
Solution 6 - CssRajanandView Answer on Stackoverflow
Solution 7 - CssOlivier CView Answer on Stackoverflow
Solution 8 - CsshappyjjdView Answer on Stackoverflow
Solution 9 - CssHakiView Answer on Stackoverflow