Pick an animation, set its timing, preview it, and copy the @keyframes and class. Browse ready-made animations below.
Scale Up Center
Scale Up Top
Scale Up Top Right
Scale Up Right
Scale Up Bottom Right
Scale Up Bottom
Scale Up Bottom Left
Scale Up Left
Scale Up Top Left
Scale Up Horizontal Center
Scale Up Horizontal Left
Scale Up Horizontal Right
Scale Up Vertical Center
Scale Up Vertical Top
Scale Up Vertical Bottom
Scale Down Center
Scale Down Top
Scale Down Top Right
Scale Down Right
Scale Down Bottom Right
Scale Down Bottom
Scale Down Bottom Left
Scale Down Left
Scale Down Top Left
Scale Down Horizontal Center
Scale Down Horizontal Left
Scale Down Horizontal Right
Scale Down Vertical Center
Scale Down Vertical Top
Scale Down Vertical Bottom
Rotate Center
Rotate Top
Rotate Top Right
Rotate Right
Rotate Bottom Right
Rotate Bottom
Rotate Bottom Left
Rotate Left
Rotate Top Left
Rotate Horizontal Center
The generator combines a preset @keyframes rule with the timing settings of the CSS animation shorthand. Choose a preset, set the timing, watch it play on a sample element, then copy a @keyframes rule and a class you can paste into any stylesheet. The collection below the generator has more than 600 more presets, grouped as Basic, Entrances, Exits, Text, Attention, and Background, and each one copies the same way.
Every setting in the toolbar maps to one part of the animation shorthand. The preview replays after each change. The preview object menu (Box, Circle, Pill, Blob, Button, Card, Text, Badge) only changes what you watch; it does not change the copied code.
The copy button opens a dialog with three tabs. All contains a comment header, the @keyframes rule, and a class. Keyframes and Class copy each part on its own. The class and the keyframes use the same name, taken from the preset, so the output below is what you get for Slide Top with a 0.5s duration, Ease Out Quad easing, and fill mode both.
In the shorthand, the first time value is always the duration and the second is the delay, so keep that order if you edit the line by hand. If the preset name already exists in your project, rename the @keyframes rule and the name inside the animation value together.
@keyframes slide-top {0% { transform: translateY(0); } 100% { transform: translateY(-100px);} }
.slide-top {
animation: slide-top 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) 0s 1 normal both;
}A CSS animation runs when the class is applied and does not restart while the class stays on the element. To replay it, for example to shake a form field after each failed submit, remove the class, force the browser to recalculate styles, and add it back. Reading offsetWidth is the usual way to force that recalculation. In React you can get the same result by changing the element's key, which remounts it; the generator's restart button works this way.
const field = document.querySelector("#email");
function shakeField() {
field.classList.remove("shake-horizontal");
void field.offsetWidth; // forces a style recalculation so the animation restarts
field.classList.add("shake-horizontal");
}
// Optional: remove the class once it has finished
field.addEventListener("animationend", () => {
field.classList.remove("shake-horizontal");
});Most problems come from settings that are easy to miss in the preview or from what the copied code leaves out.
The generator does not autoplay the preview on first load when your system asks for reduced motion, and the cards in the collection stay still until you press their restart button. The copied CSS has no reduced-motion rule, so add one in your project. Removing the animation is the simplest option, but check the end state: for a fade-in the element is simply visible, while an element that is meant to end hidden after a fade-out needs that final state set directly.
Looping attention animations such as Vibrate, Heartbeat, Pulsate, and Ping deserve the most care. WCAG 2.2.2 (Pause, Stop, Hide) requires a way to pause moving content that starts automatically, lasts more than five seconds, and is shown next to other content. A badge that pulses forever meets that description, so limit it to a few iterations or stop it after the user has seen it.
@media (prefers-reduced-motion: reduce) {
.slide-top,
.heartbeat {
animation: none;
}
}Most presets animate only transform and opacity. Browsers can usually run these without recalculating layout or repainting, so they stay smooth even on slower phones. A few groups animate properties that cost more: Background pan changes background-position and the Shadow Drop groups change box-shadow, both of which repaint the element on every frame, and the text tracking presets animate letter-spacing, which recalculates layout. Use those on small elements and avoid running many of them at once. Adding will-change to every animated element does not make things faster; it reserves memory for each layer, so save it for an element you have measured.
Updated