Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Animations

A transition fires when a style changes — for example, on hover. An animation starts by itself, can repeat forever and go through any number of in-between states. Loading indicators, blinking badges and elements appearing on the page are made this way.

Keyframes

An animation has two parts. A named @keyframes rule describes the keyframes — the states at the start (from) and at the end (to). The animation property attaches it to an element and sets the duration:

<style>
  @keyframes slide {
    from { margin-left: 0; }
    to { margin-left: 200px; }
  }
  .box { width: 60px; height: 60px; background: mediumpurple; animation: slide 2s; }
</style>
 
<div class="box"></div>

The square moved once and went back to its place. To watch again, press "Reset" above the example.

Animation properties

PropertyWhat it setsExample
animation-nameThe name from @keyframesslide
animation-durationThe length of one run2s
animation-iteration-countHow many times to repeat3, infinite
animation-directionThe directionalternate — there and back
animation-timing-functionEasing, as with transitionsease-in-out
animation-delayA pause before the start0.5s

All of this can be written in one animation line, the order of words is almost free.

Repeats and direction

infinite repeats the animation forever, alternate runs it there and back without jumping to the start:

<style>
  @keyframes pulse {
    from { transform: scale(1); }
    to { transform: scale(1.3); }
  }
  .dot { width: 40px; height: 40px; margin: 20px; border-radius: 50%; background: crimson;
    animation: pulse 0.8s ease-in-out infinite alternate; }
</style>
 
<div class="dot"></div>

Percentage keyframes

Instead of from and to you can give any points as percentages of the duration. This makes an animation of several stages:

<style>
  @keyframes jump {
    0%, 100% { transform: translateY(0); }
    30% { transform: translateY(-40px); }
    60% { transform: translateY(0); }
  }
  .ball { width: 40px; height: 40px; margin-top: 50px; border-radius: 50%; background: gold;
    animation: jump 1.2s infinite; }
</style>
 
<div class="ball"></div>

Equal keyframes are listed with commas: 0%, 100%.

Staying at the end

When an animation ends, the element returns to its normal styles. animation-fill-mode: forwards leaves it in the state of the last keyframe:

<style>
  @keyframes appear {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
  }
  .note { opacity: 0; padding: 12px; background: honeydew; animation: appear 1s 0.5s forwards; }
</style>
 
<div class="note">I appeared and stayed</div>

Without forwards the block would vanish again: its main styles have opacity: 0.

Less motion

Motion on screen tires some people or makes them feel sick, and they turn on the "reduce motion" setting in their system. The prefers-reduced-motion media query lets you respect it:

@media (prefers-reduced-motion: reduce) {
  .dot { animation: none; }
}

An animation can also be driven by page scrolling — see the lesson "Scroll-driven animations".

Common mistake

Without a duration an animation is not visible: by default animation-duration is zero, and everything ends instantly.

<style>
  @keyframes spin { to { transform: rotate(360deg); } }
  .box { width: 50px; height: 50px; margin: 10px; display: inline-block; background: steelblue; }
  .bad { animation: spin infinite linear; }
  .good { animation: spin 2s infinite linear; }
</style>
 
<div class="box bad"></div>
<div class="box good"></div>

The left square stands still, the right one spins. If an animation does not start, check the time first.

Thanks for reading!

Donate to the site — we work hard for you.