Are animations part of JavaScript or CSS?

Javascript for CSS animations

Restart keyframes animation

CSS animations have their limits, but they can be overcome with a small dose of Javascript. One of the limitations of CSS keyframe animation:

If a CSS animation has run and expired when the page loads, it cannot be restarted easily.

.animated-sky {height: 1360px; background-image: linear-gradient (to bottom, hsl (200.60%, 25%) 0%, hsl (200.60%, 55%) 20%, hsl (200.60%, 90%) 30%, hsl (200.60%, 90%) 50%, hsl (200.60%, 25%) 80%, hsl (200.60%, 55%) 100%); animation: daytime 15s; } @keyframes daytime {from {top: 0} to {top: -1000px}} / * This is how restarting the animation doesn't work * / .container: hover .animated-sky {animation: daytime 15s; }

To restart the animation on a: hover, it needs another, identical @keyframes rule with a different name.

@keyframes night {from {top: 0} to {top: -1000px}} .touch .animated-sky, .container: hover .animated-sky {animation: night 15s; }

From hover to touch start

Hovering the mouse has no equivalent on touchscreens: there is none : touch. It's not even possible to predict the reaction: maybe the touchscreen reacts to CSS: hover, maybe not. Maybe the effect will freeze on the touchscreen. : hover is still an intuitive trigger for users with the mouse, but: hover alone is not enough.

<script> let container = document.querySelector(".container"); container.ontouchstart = function () { this.classList.add("touch"); } </script>

So that's what the little line was for .touch .animated-sky in the CSS of the animation ...

Restart: restart CSS animation with Javascript

"In order to restart an animation, it must be removed then reapplied." - CSS Animations Level 1

The easiest technique to restart a CSS keyframe animation is to delete and reinsert the animated elements. Javascript cloneNode copies an element with all child nodes:

A very simple CSS animation:

HTML markup of the animation
<div class="textani"> <div class="ani t0">CSS bewegt</div> <div class="ani t1">CSS rotiert</div> <div class="ani t2">CSS blendet ein</div> <div class="ani t3">CSS blendet aus</div> <div id="trestart">restart</div> </div>
The CSS of the keyframes animation:
.textani {width: 300px; height: 200px; overflow: hidden; position: relative; } .ani {position: absolute; } .t0 {top: 30px; animation: tmovedown 2s} .t1 {top: 60px; animation: tmoveup 2s} .t2 {top: 90px; animation: tmoveleft 2s} .t3 {top: 120px; animation: tmoveright 2s} @keyframes tmovedown {from {transform: translateY (-200px)} to {transform: translateY (0px)}} #trestart {position: absolute; bottom: 0; right: 0; }
Javascript: CSS keyframes animation restart
<script> document.getElementById('trestart').onclick = function () { let clone = document.querySelector('.textani').cloneNode(); let ani = document.querySelectorAll('.ani'); let len = ani.length; for (let i=0; i<len; i++) { let clone = ani[i].cloneNode(true); ani[i].parentNode.replaceChild(clone, ani[i]); } } </script>

Javascript starts the complete animation with a click on the button by cloning all elements of the animation and replacing the original with the clone - i.e. delete and insert clone.

That's it in the simplest case.

Start and stop CSS animation with animation-play-state

animation-play-state: paused puts an animation in a waiting state until an event with animation-play-state: running the sequence of keyframes triggers.

An animation with animation-play-state: paused is started when the page is loaded, but it pauses immediately.

#banner {position: relative; } .ball {position: absolute; animation: rolerball 4s alternate infinite paused; } @keyframes rolerball {from {transform: translateX (0) rotate (0deg)} to {transform: translateX (200%) rotate (720deg)}}

If the animation is started by: hover, it will run as long as the mouse hovers over the element. As soon as the mouse leaves the animated element, the element jumps abruptly back to its position before the animation.

In many situations it seems more natural if the animation stops where the mouse leaves the element.

let banner = document.querySelector ('# banner'); banner.onmouseover = banner.ontouchstart = function (evt) {this.children [0] .style.animationPlayState = 'running'; } banner.onmouseout = banner.ontouchend = function (possibly) {this.children [0] .style.animationPlayState = 'paused'; }

The animation plays as long as the mouse hovers over the banner. If it leaves the banner, the animation pauses and resumes at this point the next time it is hovered.

Start with mouseover and touch

The CSS pseudo-selector: hover triggers a CSS transition or keyframe animation. There is no reliable hover on touch screens. The touch event, on the other hand, is not available for CSS.

A few lines of Javascript solve this:

let box = document.querySelectorAll ('. box'); for (let i = 0; i Javascript classList adds or removes a class. classList is only supported from IE 10 onwards. If IE 9 still has to be pulled, there is a classList polyfil on Github.

CSS animation visible in the browser window?

Start an animation when it comes into the viewport - that used to be the thing for far-reaching plugins or libraries like jQuery. The Javascript Intersection Observer works in all modern browsers (except IE11, which is no longer modern and shelved), is lightweight and does not burden scrolling.

The animation itself is based on a simple CSS animation.

.pen {animation: shift 3s; } @keyframes shift {from {transform: translateY (600px)} to {transform: translateY (0px)}}

However, the pen does not have a CSS class pen - it only comes into play later.

<div class="inview"> … <g id="stift"> … </g> … </div>

The script observes the element with the CSS class inview (let inview = document.querySelector (". inview")), defines the options for starting the animation: root: null, rootMargin: "0px". threshold is the intersection of the element with the visible section of the browser window. With threshold = 1, the animation would not start until the element can be fully seen.

Only when the element inview is scrolled into the browser window (observed.isIntersecting), the script adds the class to the pen .pen added.

<script> let inview = document.querySelector(".inview"); const options = { root: null, rootMargin: "0px", threshold: 0.7, }; const callback = function (entries, observer) { let observed = entries[0]; if (observed.isIntersecting) { document.querySelector("#stift").classList.add("stift"); } } const observer = new IntersectionObserver (callback, options); if (inview) { observer.observe (inview); } </script>

IE / Edge: SVG animation with CSS keyframes

Animations of SVG elements with CSS keyframes (and transitions as well) only work in IE up to and including IE11 with CSS properties such as opacity and fill, but not with transform and rotate. SVG animations with jQuery are also subject to this restriction.

CSS transitions and keyframe animations work with Chrome, Safari, Firefox and also with Microsoft Edge - also in external CSS files and can replace many Javascript animations.

External sources