Gradient Animation Loop
Four-tone CSS gradient in an infinite loop — @keyframes shifts the position of an oversized 400% background to create a fluid colour flow, zero JavaScript.
You'll get access to the interactive demo with a free account.
This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Backgrounds has 50 effects, including 6 free. Explore the category →
3 usage examples



How it works
The effect relies on two CSS properties combined. .bg-gradient-loop receives a linear-gradient(-45deg, …) with 4 colour stops and a background-size: 400% 400% that makes the background four times wider and taller than the element — colours extend well beyond the visible edges.
The @keyframes gradientLoop animation oscillates background-position between 0% 50% and 100% 50% (horizontal axis only, height locked at 50% to centre the slice). The cycle lasts 15 s with a timing-function: ease — progress accelerates through the middle and slows at the extremes, giving the colour flow a natural breathing rhythm rather than a mechanical sweep.
Because the background is 4× wider than the element, shifting the position from 0% to 100% slides the full gradient width beneath the element. The -45deg angle adds a diagonal dimension: at any given moment, the visible slice reveals a different diagonal of the gradient, creating the impression of bidirectional movement while only a single property (background-position-x) is actually animated.
.bg-label is absolutely positioned at the parent's centre via top: 50%; left: 50%; transform: translate(-50%, -50%) — this requires position: relative on the parent (.demo-preview in the demo). In a real project, replace this span with any overlay content (heading, card, CTA).
Accessibility
- prefers-reduced-motion: ABSENT from the code. The animation runs without interruption even when the OS requests reduced motion. For accessible use, add:
@media (prefers-reduced-motion: reduce) { .bg-gradient-loop { animation: none; } } - The
.bg-gradient-loopdiv carries noroleoraria-label— correct when the effect is a purely decorative background. If the element hosts a semantic section (hero, pricing…), the parent container should carry appropriate ARIA attributes (role="region",aria-label). - The
.bg-labeltext (white,text-shadow rgba(0,0,0,.5)) stays readable over the dark phases of the gradient cycle but does not meet WCAG AA on lighter phases (notably#23d5ablight teal). A semi-opaque scrim between the background and the text is required to guarantee a ratio ≥ 4.5:1. - No keyboard interaction, no focus, no user events: the effect is passive and purely visual — nothing to handle on the interactive accessibility side.
- No canvas, no SVG: the rendering is 100% CSS. Screen readers ignore the background and read only the overlay text content — no extra ARIA annotation required on the effect itself.
Browser compatibility
Requires linear-gradient, background-size, and @keyframes — available in all modern browsers since 2015. Zero external dependencies.
Without <code>background-size</code> support (IE 8 and earlier), the gradient renders statically at its natural size (100% × 100%) — no JS errors, the page remains functional.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="demo-preview">
<!-- The effect: size via CSS (width, height or min-height) -->
<div class="bg-gradient-loop">
<!-- Optional overlay content -->
<!-- (position:relative required on parent for .bg-label) -->
<span class="bg-label">Your text</span>
</div>
</div>
Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
| Gradient colours | #ee7752, #e73c7e, #23a6d5, #23d5ab | Replace the 4 hex values in linear-gradient(-45deg, …) on .bg-gradient-loop. Add extra stops for a richer spectrum. |
| Angle (-45deg) | -45deg | Direction of the apparent flow. 0deg = vertical flow, 90deg = pure horizontal flow, -45deg = diagonal bottom-left → top-right. |
| background-size (400% 400%) | 400% 400% | Zoom ratio of the background. Increase (e.g. 600% 600%) for smoother colour transitions; decrease (e.g. 200% 200%) for more noticeable colour jumps. |
| Duration (15s) | 15s | Length of one full cycle. 8s = lively and dynamic; 25s = slow and premium. Tune to the size of the surface. |
| Timing (ease) | ease | Acceleration curve of @keyframes gradientLoop. linear for a perfectly uniform flow; ease-in-out for noticeable pauses at the extremes of the cycle. |
FAQ
linear-gradient(-45deg, c1, c2, c3, …). For 6 colours, raise background-size to 600% 600% to keep transitions smooth — otherwise the colours at the extremes of the list are rarely visible during the cycle.position: relative to .bg-gradient-loop, then place your content as a child with position: relative; z-index: 10. Insert a scrim between the two — <div style="position:absolute;inset:0;background:rgba(0,0,0,.35);"></div> — to guarantee WCAG AA contrast regardless of the cycle phase.background-position is animated by the browser's CSS compositor without involving the main thread, triggering reflows, or causing costly repaints. GPU usage is negligible on modern devices, and background tabs benefit from the browser's automatic CSS animation throttling.