Master keyframe animations, transitions, and performance optimization to create smooth, professional web animations.
Animations are no longer optional in modern web design. They provide visual feedback, guide user attention, create perceived performance improvements, and add personality to interfaces. But writing CSS animations from scratch can be tedious — you need to define keyframes, manage timing functions, handle vendor prefixes, and test across browsers. That is where a CSS animation generator becomes invaluable. In this guide, we will cover the fundamentals of CSS animations, walk through common animation patterns with code examples, discuss performance best practices, and show you how to use a generator to speed up your workflow.
Before diving into animations, it is important to understand the distinction between transitions and animations, because they serve different purposes.
:hover or a class toggle via JavaScript. Transitions are perfect for hover effects, button interactions, and simple state changes.@keyframes to define multiple intermediate steps. They can run automatically on page load, loop infinitely, and handle complex multi-step sequences. Animations are ideal for loading spinners, attention-grabbing effects, and orchestrated UI sequences.A good rule of thumb: if you are animating between two states in response to a user action, use transitions. If you need a multi-step, self-running animation, use keyframes.
The @keyframes rule is the foundation of CSS animations. It defines a set of styles at various points during the animation cycle. Here is the basic syntax:
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
You can also use percentages for finer control over intermediate steps:
@keyframes bounce {
0% { transform: translateY(0); }
20% { transform: translateY(-30px); }
40% { transform: translateY(0); }
60% { transform: translateY(-15px); }
80% { transform: translateY(0); }
100% { transform: translateY(0); }
}
Once your keyframes are defined, you apply them to an element using the animation shorthand or individual properties:
.element {
animation: fadeIn 0.6s ease-out forwards;
}
The animation shorthand accepts several values. Here is the full breakdown:
animation: name duration timing-function delay iteration-count direction fill-mode play-state;
@keyframes rule to use0.5s, 2s)ease, linear, ease-in, ease-out, ease-in-out, or cubic-bezier()1 (default), 3, or infinitenormal, reverse, alternate, or alternate-reverseforwards keeps end state, backwards applies start state during delay, both does bothrunning or pausedHere are the most frequently used animation patterns in modern web design, complete with ready-to-use code.
The bread and butter of content reveals. Elements start invisible and slightly offset, then animate into their final position.
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.card {
animation: fadeInUp 0.5s ease-out forwards;
opacity: 0; /* hidden until animation starts */
}
Draws attention to an element — commonly used for notification badges, CTAs, or status indicators.
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.notification-badge {
animation: pulse 2s ease-in-out infinite;
}
A rotating border creates a smooth loading indicator. This is one of the most recognizable UI patterns on the web.
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #334155;
border-top-color: #6366f1;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
A gradient sweep that simulates content loading. This is the modern alternative to the old spinner — used by Facebook, YouTube, and most major platforms.
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.skeleton {
background: linear-gradient(90deg, #1e293b 25%, #334155 50%, #1e293b 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: 4px;
}
A simple but effective interaction pattern. Uses transitions rather than keyframes because it responds to user input.
Poorly optimized animations can cause jank, battery drain, and a bad user experience. Follow these principles to keep your animations smooth.
This is the single most important performance rule. The browser rendering pipeline has three stages:
Animating transform and opacity skips straight to the composite step — they are handled by the GPU and do not trigger layout or paint recalculations. Animating width, height, margin, padding, top, or left forces the browser to recalculate layout and repaint, which is expensive.
transform: translateX/Y/Z() instead of left/top/right/bottom for movement. Use transform: scale() instead of width/height for size changes.
The will-change property hints to the browser that an element will be animated, allowing it to optimize in advance:
.animated-element {
will-change: transform, opacity;
}
However, do not apply will-change to too many elements. It creates new compositor layers that consume GPU memory. Apply it only to elements you know will animate, and remove it after the animation completes if possible.
Some users have vestibular disorders or motion sensitivity. Always respect the prefers-reduced-motion media query:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
This disables or minimizes animations for users who have requested reduced motion in their system settings. It is both a best practice and an accessibility requirement.
Reading layout properties (like offsetWidth, offsetHeight) and then writing styles in the same frame forces the browser to perform synchronous layout recalculations. If you need to read values for animation logic, batch your reads and writes separately.
The timing function defines the acceleration curve of your animation. Choosing the right one makes the difference between an animation that feels natural and one that feels mechanical.
A popular custom easing for a snappy, playful feel is cubic-bezier(0.68, -0.55, 0.265, 1.55), which creates a slight overshoot effect — the element moves past its target and then settles back.
Writing keyframes by hand is manageable for simple effects, but complex animations with multiple steps, precise timing, and custom easing curves benefit from a visual tool. A CSS animation generator lets you:
Design, preview, and copy production-ready CSS animations in seconds.
Try the Free Generator →CSS transitions animate property changes between two states and require a trigger like hover or a class change. CSS animations use @keyframes to define multiple intermediate states and can run automatically. Transitions are simpler for state changes; animations are more powerful for complex, multi-step sequences.
Most CSS properties with continuous numeric or color values can be animated, including transform, opacity, color, background-color, width, height, margin, padding, border-radius, box-shadow, and font-size. Properties like display cannot be smoothly animated.
Stick to animating only transform and opacity. These properties skip the layout and paint phases and are handled by the GPU compositor. Avoid animating width, height, margin, and top/left, which trigger expensive layout recalculations. Use will-change sparingly on elements you plan to animate.
Yes. The Web Animations API (element.animate()) provides programmatic control over CSS animations, including play, pause, reverse, and seek. You can also toggle animation-play-state between paused and running via JavaScript class changes for simpler use cases.
For simple UI animations (hover effects, loading indicators, page transitions), pure CSS is ideal — it requires no dependencies, is performant, and is easy to maintain. For complex multi-step sequences, scroll-linked animations, or timeline-based orchestration, GSAP and similar libraries offer superior control and features. Many projects use a combination of both.