I’m trying to create a website in which there are some simple CSS animations:
fade-in
: Causes the element to fade into view, anderror
: Causes the element to turn red and shake for a brief moment.
When I trigger the error
animation through JS, once it’s done, the fade-in
animation plays as well, which is not desired. Here’s the CSS and JS:
style.css:
...
/* All children of the `splash` class are subject to the `fade-in` animation */
.splash * {
animation: fade-in 1s ease-in;
opacity: 1;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.error {
animation: shake 0.4s ease-in-out;
border-color: red;
}
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(-5px); }
50% { transform: translateX(5px); }
75% { transform: translateX(-5px); }
100% { transform: translateX(0px); }
}
.no_transition {
animation: none;
transition: none;
}
...
script.js:
...
function err(elem, msg) {
if (msg) alert(msg);
// start the transition
elem.classList.add('error');
elem.disabled = true;
setTimeout(() => {
// 1 second later, remove the `error` class.
elem.classList.add('no_transition');
elem.classList.remove('error');
elem.disabled = false;
elem.classList.remove('no_transition'); // this is what triggers the `fade-in` animation again
}, 1000);
}
...
Since adding / removing a class will trigger the CSS animation, I tried creating a separate class (no-transition
) that blocks all animations and transitions. However, once I remove it, fade-in
triggers once again.
Is there a way to work around this, and add / remove these CSS classes without triggering the fade-in
animation?
2
Answers
You can try overriding the class when removing it by setting the opacity attribute from JavaScript:
Another thing to try is by adding "!important" to force "animation: none" to be applied, or some other way to highen the specificity.
You can also override the opacity in .no_transition:
But you should of course try using CSS specificity over !important.
You could set your
animation
so that it contains the two sets of animations, this way the first one wouldn’t restart:But that implies the
fade-in
animation is always active when theshake
one is.So it actually sounds like you don’t want
fade-in
to be an animation, but a transition instead. If you have trouble making it kick when appending your elements, then see this Q/A. Basically, you have to wait for (or force) a reflow before you set the target of the animation.But, since you’re gonna use JS to control these transitions and animations, then it’s even better to use the Web Animation API to control these directly rather than do a complex round-trip through DOM then CSSOM.