Home / Snippets / Color & Theming /
Animated background
A slowly shifting gradient background using @keyframes, background-size: 200% 200%, and background-position animation.
Quick implementation
.animated-bg {
background: linear-gradient(
135deg,
oklch(0.30 0.18 280),
oklch(0.42 0.20 240),
oklch(0.35 0.16 200),
oklch(0.28 0.14 260)
);
background-size: 200% 200%;
animation: bg-shift 8s ease infinite;
}
@keyframes bg-shift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@media (prefers-reduced-motion: reduce) {
.animated-bg {
animation: none;
background-position: 0% 50%;
}
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building a CSS animation library.
Goal: A smoothly animating gradient background using @keyframes and background-position — no JavaScript.
Technical constraints:
- Use a linear-gradient with at least four oklch() color stops at 135deg.
- Set background-size: 200% 200% to create a larger canvas than the element.
- Animate background-position from 0% 50% to 100% 50% and back using @keyframes.
- Use an infinite loop with ease timing and a duration between 6s and 12s for a slow, ambient feel.
- Use oklch() for all colors — no hex or rgba().
- Include @media (prefers-reduced-motion: reduce) to freeze the animation at a static position.
Framework variant (pick one):
A) Vanilla CSS utility class that can wrap any element.
B) React component — accept colors array, duration, and angle as optional props.
Edge cases to handle:
- Ensure the gradient direction and color stops are tuned so no abrupt color jump occurs at the loop boundary.
- The static fallback (reduced-motion) should still look intentional, not broken.
- Works on both block-level containers and inline elements with display: inline-block.
Return CSS.
Why this matters in 2026
Animated gradient backgrounds are one of the most requested UI effects for hero sections, loading states, and ambient UI. The background-position trick achieves smooth color shifting without animating gradient stops directly — which would force full repaints. This approach keeps the animation cheap and is supported in every modern browser without JavaScript or a canvas element.
The logic
The gradient is painted on a canvas twice the element's width and height (background-size: 200% 200%). The @keyframes rule shifts the viewport over this larger canvas by animating background-position — moving from the left edge to the right edge and back. Because the gradient has multiple overlapping color stops, panning across it produces a smooth color transition rather than a sharp jump. Crucially, background-position is a composited property in most browsers, so the animation runs without triggering layout or paint recalculation.
Accessibility & performance
Always include @media (prefers-reduced-motion: reduce) to stop the animation for users with vestibular sensitivities — a looping background shift is exactly the kind of movement this preference is designed to address. From a performance perspective, animating background-position is far cheaper than animating background-image or swapping gradient definitions. Keep the duration above 6 seconds; fast-cycling gradients are distracting and create unnecessary GPU work.