AI CSS Animations

Blog · · Maxwell Prehoda

Kinetic Typography With AI: Prompts and CSS That Don't Look Generated

Our Motion Prompts directory collects motion pieces from creators' posts, mostly made with Claude Opus 5.5. Kinetic type is tagged on more than 70 of them, second only to product UI. And of the 41 runs of the viral motion designer showreel prompt we catalogued, 31 lean on kinetic type.

A lot of that is the model's choice, not the prompter's. @zheke typed "Hello Opus 5.5 show me what an incredible motion designer you are." and got back a reel of kinetic type and shapes. @davidmarcus asked for "a punchy and modern short video for social," and that one's tagged kinetic type too. Give a model words and a timeline and it animates the words.

It's also the easiest kind of motion to get wrong. Everyone reads, so everyone notices when reading gets hard. Here's what gives AI text animation away, a prompt that avoids it, and two CSS snippets you can use today.

Why AI kinetic typography looks generated

Watch enough of it and the same tells keep showing up.

  • Every word does a different trick. One slides, the next scales, the next scrambles, the next flips in 3D. It looks like a demo of an animation library, not a piece with a point.
  • No hierarchy. Every word gets the same size, weight and screen time, so nothing lands. If everything is emphasized, nothing is.
  • Too fast to read. Models pace for impressive, not for reading. Lines leave before you finish them.
  • Everything centered. Line after line, dead center, same spot. That's a stack, not a layout.
  • Blur and glow on everything. Once, a blur suggests speed. On every word, it's fog.
  • Motion that has nothing to do with the words. "Stop" keeps drifting. "Rise" slides in from the left. The move was picked because it looked good, not because the word asked for it.

Six rules for kinetic type animation that looks directed

None of this is new. It's what motion designers already do. The model just won't do it unless you ask.

1. One or two moves for the whole piece

Pick one move for lines coming in, and maybe a second for the words that matter. Use them everywhere. Repetition is what makes a piece feel designed: the viewer learns the grammar in a couple of seconds and then just reads. Give every word its own trick and they watch the tricks instead.

2. One word per line carries the weight

Decide which word in each line matters and make it bigger, heavier or longer on screen. Everything else in the line is support, set smaller and quieter. If you can't pick the word, the line has too many ideas in it.

3. Pace it for reading

Our rule of thumb, not a cited number: no more than about three words per second on screen, and hold the last line for at least a second, longer if it's the point. By that math, a 10-second piece fits roughly 20 to 25 words once you leave room for holds. If you have to pause the video to read it, it's too fast.

4. Make the motion match the meaning

The strongest kinetic piece in the directory is built on this idea. @Gdgtify's "BUILD THE FLOOR" is a 20-second spoken-word film: one self-contained HTML file, 1080×1080, 60fps, drawn with SVG and Canvas. The prompt gives a palette and three type roles: a high-contrast serif for the speech, a heavy grotesque for load-bearing words, a restrained monospace for timing marks. It bans the obvious clichés and timestamps every line of the storyboard.

Then it gives words jobs: "WAIT is a lintel… VOICE is a support… FLOOR is a platform." Those roles have to come from the letterforms themselves, not from illustrations placed behind the text. By the end, the final sentence settles onto a platform built from words that came earlier.

You don't have to go that far. One word that does what it says, a "drop" that drops or a "split" that splits, is enough to make the rest of the piece feel intentional.

5. Entrances ease out, exits ease in

An entrance should start fast and settle softly (ease-out), so the word arrives and stays put. An exit should start slow and leave fast (ease-in), so it gets out of the way. The same curve both ways, or a bounce on everything, looks automatic.

6. Let things sit still

Stillness is when people read. BUILD THE FLOOR holds its full final declaration for two seconds with no new text, and the prompt asks for at least one 400ms moment of absolute stillness. Constant motion feels busy. A beat where nothing moves makes the next move land.

A kinetic typography prompt you can copy

This one's ours. It puts all six rules into the prompt so the model can't fall back on its defaults. Fill in the brackets.

Make a 12-second kinetic typography piece for [Instagram at 1:1 / X at 16:9].

Script, exact words, exact order. Don't add, cut or change anything:
"[First line, with the *key* word marked.]"
"[Second line, with its *key* word marked.]"
"[Last line, the one people should remember.]"
The word between asterisks carries each line. Don't render the asterisks.

Type: [a heavy grotesque] for the key words. [a quieter serif or sans] for everything else. No other typefaces.
Hierarchy: the key word in each line is bigger, heavier or on screen longer than the words around it.

Motion: two moves for the whole piece. Lines enter by rising out of a mask. Key words [scale up / shift weight / slide in from the side]. Nothing else moves unless it means something.
If a word describes motion or a shape (drop, split, grow, stop), let that one word do it. Once, not everywhere.
Entrances ease out, exits ease in. Include at least one moment where nothing moves.

Pacing: no more than about three words per second on screen. Every line is readable before the next one starts. Hold the last line, still, for at least 1.5 seconds.

Avoid: a different effect on every word, letter scrambles, glitch, glow, blur on everything, particles, gradient text, centering every line by default.

Build: one self-contained HTML file, [1080x1080 / 1920x1080], 60fps. Compute every frame from a seek(t) function, with no CSS transitions or timers, so it can be rendered frame by frame.

Check: render a frame from the middle of each line and one from the final hold. Look at them. Fix anything clipped, overlapping, too small or on screen too briefly to read, then show me.

Giving the script word for word, with "don't add, cut or change anything," stops the model writing its own slogans. Marking the key word yourself beats hoping it picks the same one you would. The check step at the end matters: Claude Code can screenshot its own frames, and it catches clipped and overlapping text before you see it.

If you have a visual style, attach it. @gizakdag gave Opus 5.5 their own graphics as a reference, alongside a reworked showreel prompt, for a short typographic film about overthinking. It's the fastest way to get your style instead of the model's.

Kinetic typography CSS you can paste

For a headline on a web page, you don't need a film or a prompt. These two are plain CSS. Paste the HTML and the CSS into a blank page and they run.

Word-by-word rise

<h1 class="rise">
  <span style="--i: 0">Say</span>
  <span style="--i: 1">less,</span>
  <span style="--i: 2">mean</span>
  <span style="--i: 3">more.</span>
</h1>
.rise {
  font: 800 clamp(2.5rem, 8vw, 6rem)/1.05 system-ui, sans-serif;
}

.rise span {
  display: inline-block;
  animation: rise 700ms cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: calc(var(--i) * 90ms); /* after the shorthand, which resets it */
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(0.4em);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* The base styles are the final state, so this just shows the text. */
@media (prefers-reduced-motion: reduce) {
  .rise span {
    animation: none;
  }
}

Each word is a span with its own --i, and animation-delay: calc(var(--i) * 90ms) staggers them. The spans need display: inline-block because transforms don't apply to inline elements. The both fill mode keeps each word hidden while it waits and in place when it's done. The blur is small and clears as the word lands, which is the only place a blur belongs.

Splitting by word is fine for screen readers. If you split by letter, put the full text in an aria-label on the heading and add aria-hidden="true" to the letters.

Masked line reveal

<h2 class="reveal">
  <span class="line"><span style="--i: 0">Nobody reads</span></span>
  <span class="line"><span style="--i: 1">the second line</span></span>
  <span class="line"><span style="--i: 2">unless you earn it.</span></span>
</h2>
.reveal {
  font: 700 clamp(2rem, 6vw, 4.5rem)/1.1 system-ui, sans-serif;
}

.reveal .line {
  display: block;
  overflow: hidden;
}

.reveal .line > span {
  display: block;
  padding-bottom: 0.1em; /* room for descenders inside the mask */
  animation: reveal 800ms cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(var(--i) * 140ms);
}

@keyframes reveal {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal .line > span {
    animation: none;
  }
}

Each line sits in a wrapper with overflow: hidden. The inner line starts at translateY(100%), a full line below where it belongs and out of sight, then slides up to 0. Percentages in translateY are relative to the element itself, so it works at any font size. The bottom padding gives descenders room, so a "g" or "y" doesn't get clipped by the mask.

Both snippets end with a prefers-reduced-motion block that turns the animation off. The base styles are the final state, so people who've asked for less motion just see the finished headline.

More text animation

For a pure CSS take on the "make it move" look, start with our kinetic typography snippet. For more copy-paste effects (typing, reveals, gradients, glitch, 3D titles), see the Text Animations directory. For full AI-made kinetic type pieces and the prompts behind them, open the Motion Prompts directory and filter by Kinetic type. Watch a few before you write your own prompt. You'll spot the tells faster in someone else's video than in yours.