Kort fortalt
- Browsere kan ikke interpolere mellem to gradientværdier, så en CSS-animeret gradient flytter, fader eller transformerer gradienten i stedet for at animere den direkte.
- Den klassiske teknik gør baggrunden større end elementet og animerer background-position, hvilket virker overalt, men gentegner hver frame.
- Ved at registrere brugerdefinerede egenskaber med @property kan browseren animere enkelte farver, vinkler og positioner inde i en gradient.
- At animere transform eller opacity på et separat gradientlag er som regel den billigste løsning, fordi browsere ofte kan sammensætte det uden at gentegne.
- Hver gradientanimation bør stoppe eller blive næsten stille, når brugeren har bedt om reduceret bevægelse.
På denne side
En CSS-animeret gradient er en gradientbaggrund, der skifter farve eller position over tid. Der er en hage: skriver du to forskellige gradienter i en @keyframes-regel, blander browsere ikke mellem dem, de springer. Derfor animerer hver teknik, der virker, noget ved siden af gradienten: dens position, de brugerdefinerede egenskaber inde i den eller laget, den er malet på. Hvilken du vælger, afgør, hvor blød den ser ud, og hvor meget arbejde browseren har med hver frame.
For designsiden, altså hvornår bevægelse hjælper et brand, og hvordan du timer den, se animerede gradientbaggrunde. Denne guide er koden.
Teknik 1: flyt en overstor baggrund
Gør gradienten to til fire gange så stor som elementet med background-size, og animér derefter background-position, så en anden del af den vises over tid. Den virker i alle browsere og kræver ingen JavaScript. Brug alternate, så bevægelsen vender jævnt i stedet for at springe tilbage til starten.
.hero {
background-color: #1e1b4b;
background-image: linear-gradient(120deg, #1e1b4b, #7c3aed, #f472b6, #fb923c);
background-size: 300% 300%;
animation: pan 18s ease-in-out infinite alternate;
}
@keyframes pan {
from { background-position: 0% 50%; }
to { background-position: 100% 50%; }
}Prisen: background-position kan browsere ikke flytte alene på grafikkortet, så elementet gentegnes ved hver frame. På en knap er det ingenting. På en helskærmshero er det reelt arbejde, der kører, så længe siden er åben.
Teknik 2: animér farvestop med @property
Brugerdefinerede egenskaber er normalt strenge, som ikke kan interpoleres. Registrerer du en med @property, får den en type, som <color>, <angle> eller <percentage>, og typede egenskaber animeres jævnt. Brug dem inde i gradienten, og du kan animere farverne, vinklen eller et stops position direkte. @property understøttes i alle nuværende større browsere. Tjek caniuse, hvis du understøtter ældre.
@property --from {
syntax: "<color>";
inherits: false;
initial-value: #7c3aed;
}
@property --to {
syntax: "<color>";
inherits: false;
initial-value: #f472b6;
}
@property --angle {
syntax: "<angle>";
inherits: false;
initial-value: 120deg;
}
.hero {
background: linear-gradient(var(--angle), var(--from), var(--to));
animation: shift 16s ease-in-out infinite alternate;
}
@keyframes shift {
to {
--from: #0891b2;
--to: #fb923c;
--angle: 200deg;
}
}Denne teknik gentegner stadig hver frame, ligesom den første. Fordelen er kontrol: du kan flytte ét skær i en mesh-gradient, rotere en konisk kant eller skifte en brandgradient mod en anden palet uden overstore baggrunde.
Teknik 3: transformér et gradientlag
Læg gradienten på et pseudoelement, der er meget større end elementet, og animér dets transform, for eksempel en langsom rotation eller drift. Browsere kan som regel flytte et transformeret lag på grafikkortet uden at gentegne det, så det er den billigste måde at animere en stor gradient på. will-change: transform antyder, at laget bør promoveres på forhånd.
.hero {
position: relative;
overflow: hidden;
isolation: isolate;
}
.hero::before {
content: "";
position: absolute;
inset: -50%;
z-index: -1;
background: conic-gradient(from 0deg, #1e1b4b, #7c3aed, #f472b6, #0891b2, #1e1b4b);
animation: turn 40s linear infinite;
will-change: transform;
}
@keyframes turn {
to { transform: rotate(1turn); }
}Teknik 4: krydsfade to gradienter
Stak to gradientlag, og animér opacity på det øverste. Opacity er også en egenskab, der egner sig til compositoren, så fadet er jævnt og billigt. Det passer til langsomme stemningsskift, som en dagpalet, der fader over i en natpalet, og det lader de to gradienter være helt forskellige i opbygning.
.sky {
position: relative;
isolation: isolate;
background: linear-gradient(180deg, #7dd3fc, #fde68a);
}
.sky::after {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background: linear-gradient(180deg, #0f172a, #7c3aed);
animation: dusk 20s ease-in-out infinite alternate;
}
@keyframes dusk {
from { opacity: 0; }
to { opacity: 1; }
}Sådan vælger du en teknik
| Teknik | Browserens arbejde pr. frame | Bedst til |
|---|---|---|
Flytning af background-position | Gentegning | Små elementer, knapper, tekst |
@property-farver og vinkler | Gentegning | Præcise farveskift, roterende kanter |
transform på et lag | Som regel kun sammensætning | Store baggrunde i fuld skærm |
opacity-krydsfade | Som regel kun sammensætning | Langsomme stemnings- eller paletskift |
Mål i stedet for at gætte. I Chrome DevTools fremhæver panelet Rendering med paint flashing de områder, der gentegnes hver frame, og en Performance-optagelse viser, hvor stor en del af hver frame der går til tegning. CSS-gradienters ydeevne gennemgår det.
Reduceret bevægelse og god opførsel
Nogle mennesker bliver svimle eller forstyrrede af bevægelse i baggrunden, og operativsystemer lader dem bede om mindre af den. Respektér det med en prefers-reduced-motion-forespørgsel, der stopper animationen og efterlader en stille, færdig frame. Guiden om reduceret bevægelse forklarer, hvad der tæller som bevægelse, det er værd at fjerne.
@media (prefers-reduced-motion: reduce) {
.hero,
.hero::before,
.sky::after {
animation: none;
}
}Undgå
- Cyklusser hurtigere end omkring 8 sekunder på store områder
- Regnbueagtig farvetonerotation over hele siden
- Bevægelse bag brødtekst, folk skal læse
- Animationer, der bliver ved med at køre, når fanen har stået ubrugt i minutter
Gør
- Langsom, stemningsskabende bevægelse inden for én farvefamilie
- Bevægelse i heroen, ro i indholdet
- En rolig stille frame til reduceret bevægelse
- Test på en beskeden laptop og en telefon, ikke kun på en hurtig stationær
Spørgsmål, folk stiller
Kan man animere en CSS-gradient?
Ikke direkte: browsere springer mellem to gradientværdier i keyframes. Animér i stedet background-position, registrerede brugerdefinerede egenskaber brugt inde i gradienten eller transform og opacity på et gradientlag.
Hvad er den blødeste måde at animere en gradientbaggrund på?
At animere transform eller opacity på et separat gradientlag, fordi browsere som regel kan håndtere dem uden at gentegne.
Hvordan animerer jeg gradientfarver i CSS?
Registrér hver farve med @property med syntax: "<color>", brug egenskaberne i gradienten, og ændr dem i @keyframes.
Gør animerede gradienter en side langsom?
Små betyder sjældent noget. Store animerede baggrunde, der gentegnes hver frame, kan koste batteri og jævnhed, så foretræk transform eller opacity, og mål med DevTools.
Hvordan respekterer jeg reduceret bevægelse i gradientanimationer?
Pak en animation: none-regel ind i @media (prefers-reduced-motion: reduce), så brugere, der beder om mindre bevægelse, ser en stille frame.
Skrevet af Gradiently
Holdet bag Gradiently, et designværktøj bygget om Marks: levende gradienter, der får alt, du designer, til at ligne dig.
Se vores profil


