Skip to content
T
Tools.Town
Free Online Tools for Everyone
Design Tools

CSS Animations Explained: @keyframes, Easing, and the Animation Shorthand

A complete guide to CSS keyframe animations — how @keyframes work, what every part of the animation shorthand does, which properties to animate for 60fps, and how to build it all visually.

23 June 2026 4 min read By Tools.Town Team Fact Checked

Key Takeaways

  • Yes
  • transform and opacity
  • It keeps the styles from the final keyframe after the animation ends, instead of snapping the element back to its original appearance

What a CSS animation actually is

A CSS animation has two halves that always work together. The first is a @keyframes rule that describes what changes — a list of styling snapshots at different points along a timeline. The second is the animation shorthand applied to an element, which describes how those snapshots play: how long they take, how they accelerate, how many times they repeat, and what happens before and after. Miss either half and nothing moves.

The CSS Animation Generator builds both halves for you from a visual preview, but understanding the pieces makes the output far easier to customise. Let’s walk through them.

The @keyframes rule

A keyframes rule is a named timeline. You give it a name, then list percentage offsets from 0% (the start) to 100% (the end), each with the styles the element should have at that moment:

@keyframes slideUp {
  0%   { transform: translateY(40px); opacity: 0; }
  100% { transform: translateY(0);    opacity: 1; }
}

The browser interpolates smoothly between the offsets you define. You don’t have to list every percent — only the points where something meaningful changes. A simple fade needs just 0% and 100%; a bounce needs a few intermediate stops so the element can overshoot and settle. The keywords from and to are aliases for 0% and 100%.

The name you choose matters because the animation shorthand refers to it. It must be a valid CSS identifier: start with a letter, then letters, digits, hyphens, or underscores. The generator validates this for you and warns if the name is invalid, which is a common reason an animation silently fails to run.

The animation shorthand, field by field

Once you have keyframes, you bind them to an element. The longhand version is verbose:

.element {
  animation-name: slideUp;
  animation-duration: 600ms;
  animation-timing-function: ease-out;
  animation-delay: 0ms;
  animation-iteration-count: 1;
  animation-direction: normal;
  animation-fill-mode: both;
}

The shorthand packs all of that into one line, in a fixed order:

.element {
  animation: slideUp 600ms ease-out 0ms 1 normal both;
}

Here is what each value controls:

  • name — which @keyframes rule to play.
  • duration — how long one cycle takes. The generator works in milliseconds for precision.
  • timing function (easing) — the acceleration curve. ease starts and ends slowly; linear is constant; ease-in/ease-out weight the slowdown to one end. A spring-like cubic-bezier() can overshoot for a playful feel.
  • delay — how long to wait before starting.
  • iteration count — how many times to repeat, or infinite for continuous motion like spinners.
  • directionnormal, reverse, alternate (ping-pong), or alternate-reverse.
  • fill mode — what the element looks like outside the animation window (covered below).

Because the order is fixed and easy to get wrong by hand, generating the shorthand is one of the biggest time-savers. Build it visually with the CSS Animation Generator and you never have to remember whether delay comes before or after iteration count.

Easing: the difference between cheap and polished

Easing is what separates motion that feels mechanical from motion that feels designed. A linear fade looks robotic; the same fade with ease-out feels like it’s decelerating naturally to a stop. As a rule of thumb, entrances look best with ease-out (fast in, gentle landing), exits with ease-in, and looping attention-grabbers with ease-in-out. When you want personality — a button that springs, a badge that pops — reach for a back-easing cubic-bezier that overshoots slightly before settling.

Fill modes, demystified

Fill mode is the setting people most often get wrong. By default (none), an element snaps to its keyframe styles only while the animation is running, then reverts to its normal CSS. That means a fade-in element is fully visible before the animation starts and again after it ends — usually not what you want.

  • forwards holds the final keyframe after the animation finishes.
  • backwards applies the first keyframe during any start delay.
  • both does both, which is the safe default for entrance animations.

If your faded-in element flashes visible before animating, switching fill mode to both almost always fixes it.

Animate the right properties

Not all properties are equal. Animating transform and opacity is cheap because the browser hands the work to the GPU compositor — no layout, no repaint. Animating geometry properties like width, height, top, or margin forces the browser to recalculate layout on every frame, which causes jank on slower devices. Every preset in the CSS Animation Generator sticks to transform and opacity for exactly this reason, so the motion you copy stays smooth.

If you find yourself wanting to move or resize an element, reach for a transform instead of changing its box. Our companion CSS transform guide explains how translate, scale, rotate, and skew combine — those same functions are what your keyframes should animate between.

Putting it together

Suppose you want a card that slides up and fades in once, holding its final position. You’d define a slideUp keyframes rule, then apply animation: slideUp 500ms ease-out 0ms 1 normal both;. The both fill mode keeps it hidden during any delay and visible after it lands; the ease-out curve makes the landing feel soft; and because you animated transform and opacity, it runs at 60fps.

That’s the whole model: define the timeline, bind it with the right timing, animate compositor-friendly properties, and pick the fill mode that matches your intent. Build it once in the CSS Animation Generator, copy the output, and tune the numbers with the understanding above.

Respect user preferences

One last note: some people enable “reduce motion” in their operating system because animation makes them dizzy or distracted. Wrap non-essential animations in a media query so they’re disabled for those users:

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

It’s a small addition that makes your interface considerate as well as lively.

Advertisement

Try CSS Animation Generator — Free

Apply what you just learned with our free tool. No sign-up required.

Try CSS Animation Generator

Frequently Asked Questions

Do I need both @keyframes and the animation shorthand?
Yes. The @keyframes rule defines what changes over time; the animation shorthand binds those keyframes to an element and sets its duration, easing, delay, repeat count, direction, and fill mode. One without the other does nothing.
Which properties are cheap to animate?
transform and opacity. Browsers can animate them on the GPU compositor without recalculating layout or repainting, so they stay smooth even on weaker devices. Avoid animating width, height, top, left, or margin where possible.
What does animation-fill-mode: forwards do?
It keeps the styles from the final keyframe after the animation ends, instead of snapping the element back to its original appearance. Use it for entrance animations that should hold their finished state.

Was this guide helpful?

Your feedback helps us improve our content.

Continue Reading

All Design Tools Guides

Get the best Design Tools tips & guides in your inbox

Join 25,000+ users who get our weekly design tools insights.