cssgridgen

CSS Animation Generator

Keyframes, transitions, and a draggable easing curve.

Open in
slide-up
keyframes + shorthand
@keyframes slide-up {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

.element {
  animation: 420ms cubic-bezier(0.16, 1, 0.3, 1) both slide-up;
}

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

Easing is the part that makes it feel right

Duration gets all the attention and easing does all the work. A 300ms fade with the wrong curve feels mechanical; the same fade on cubic-bezier(0.16, 1, 0.3, 1) feels considered. Drag the two control points and watch the preview change — it is much faster than guessing at four numbers.

How to use it

  1. Choose animation or transition

    Animations run on their own from a keyframes rule. Transitions run when a property changes and need a trigger.

  2. Pick the motion

    Fade, slide, scale, pulse, spin, shake and bounce, each with sensible defaults for its own kind of movement.

  3. Shape the easing

    Drag either control point on the curve. Pulling a point above the top edge produces overshoot, which is how bouncy motion is made.

  4. Set the timing

    Duration, delay, iteration count, direction and fill-mode. Hit Replay to watch it again.

  5. Copy the CSS

    You get the @keyframes rule, the animation shorthand, and a prefers-reduced-motion block already written.

Transition or animation?

A transition interpolates between two states and needs something to trigger it — a hover, a class change, a new value. An animation plays by itself from a @keyframes rule, can have any number of steps, and can repeat. If your motion has a middle, you want an animation.

Animate transform and opacity, nothing else

Those two are handled by the compositor without recalculating layout or repainting, so they hold 60fps on almost anything. Animating width, height, top or margin forces the browser to redo layout on every single frame, which is what janky animation actually is. Slide things with translateY rather than top.

Overshoot lives outside the box

The easing editor lets you drag a control point above the top edge, giving Y values greater than 1. That makes the animation travel past its destination and settle back — the basis of every bouncy, springy interface animation. cubic-bezier(0.34, 1.56, 0.64, 1) is the classic version.

Reduced motion is not optional

Vestibular disorders make large or repeating motion genuinely unpleasant, and honouring prefers-reduced-motion is a WCAG requirement rather than a nicety. Every export from this tool ships with the media query already in place, so the default is the accessible one.

Frequently asked questions

What is the difference between CSS transition and animation?
A transition runs when a property changes, needs a trigger like :hover, and only goes from A to B. An animation runs on its own from a @keyframes rule, can have any number of steps, and can loop. Use a transition for state changes, an animation for anything with more than two points.
How do I write CSS keyframes?
Name the sequence with @keyframes slide-up { from { … } to { … } }, then reference the name in the animation shorthand. Use percentages instead of from/to when you need intermediate steps.
What does cubic-bezier do?
It defines the easing curve as two control points, so cubic-bezier(0.16, 1, 0.3, 1) starts fast and settles slowly. Y values above 1 or below 0 make the animation overshoot and come back, which is how bouncy motion is built. Drag the two dots on the curve above to feel it.
Why does my element snap back when the animation ends?
Because the default animation-fill-mode is none, which discards the keyframe styles the moment the animation finishes. Set forwards to hold the final frame, or both to also apply the first frame during any delay.
Which CSS properties are cheap to animate?
transform and opacity, because the compositor handles them without recalculating layout or repainting. Animating width, height, top or margin forces layout on every frame, which is what janky animation usually is.
How do I respect prefers-reduced-motion?
Wrap a kill switch in a media query: @media (prefers-reduced-motion: reduce) { .element { animation: none; } }. Motion can trigger nausea and migraines for some people, and honouring the setting is a WCAG requirement. The CSS this tool emits includes the block.