CSS och webb

Animerade gradientbakgrunder i CSS, gjorda rätt

Gradienter kan inte animeras direkt, men allt runt dem kan. Fyra tekniker, vad var och en kostar webbläsaren och hur du håller rörelsen lugn och valfri.

GradientlyVerifierat Gradiently-konto··4 minuters läsning
Omslag: Pine Afternoon · GR·6MTX·YD

Kortversionen

  • Webbläsare kan inte interpolera mellan två gradientvärden, så en animerad gradient i CSS flyttar, tonar eller transformerar gradienten i stället för att animera den direkt.
  • Den klassiska tekniken gör bakgrunden större än elementet och animerar background-position, vilket fungerar överallt men ritas om varje bildruta.
  • Om du registrerar egna egenskaper med @property kan webbläsaren animera enskilda färger, vinklar och positioner inuti en gradient.
  • Att animera transform eller opacity på ett separat gradientlager är oftast det billigaste alternativet, eftersom webbläsare ofta kan sammanfoga det utan att rita om.
  • Varje gradientanimation bör stanna, eller nästan stå still, när användaren har bett om reducerad rörelse.
På den här sidan

En animerad gradient i CSS är en gradientbakgrund som ändrar färg eller position över tid. Det finns en hake: om du skriver två olika gradienter i en @keyframes-regel blandar webbläsarna inte mellan dem, de hoppar. Därför animerar varje fungerande teknik något bredvid gradienten i stället: dess position, de egna egenskaperna inuti den eller lagret den är målad på. Vilken du väljer avgör hur mjuk den ser ut och hur mycket arbete webbläsaren gör i varje bildruta.

Tre ögonblick ur en långsam animation. Riktning och färg rör sig båda, men paletten förblir en familj.

För designsidan, när rörelse hjälper ett varumärke och hur du tar tempot, se animerade gradientbakgrunder. Den här guiden är koden.

Teknik 1: flytta en överdimensionerad bakgrund

Gör gradienten två till fyra gånger så stor som elementet med background-size och animera sedan background-position så att en annan del av den syns över tid. Det fungerar i alla webbläsare och kräver ingen JavaScript. Använd alternate så att rörelsen vänder mjukt i stället för att hoppa tillbaka till början.

css
.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%; }
}
Den klassiska animerade gradienten. Långsamma varaktigheter på 12 till 30 sekunder känns stillsamma snarare än stökiga.

Kostnaden: background-position kan inte flyttas enbart på grafikkortet, så elementet ritas om i varje bildruta. På en knapp är det ingenting. På en helskärmshero är det verkligt arbete som pågår så länge sidan är öppen.

Teknik 2: animera färgstopp med @property

Egna egenskaper är normalt strängar, som inte kan interpoleras. Om du registrerar en med @property får den en typ, som <color>, <angle> eller <percentage>, och typade egenskaper animeras mjukt. Använd dem inuti gradienten så kan du animera färgerna, vinkeln eller positionen för ett stopp direkt. @property stöds i alla nuvarande stora webbläsare. Kolla caniuse om du stöder äldre.

css
@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;
  }
}
Färger och vinkel som animeras inuti gradienten. Oregistrerade egenskaper skulle hoppa i stället för att blandas.
De två ändpunkterna i animationen ovan. Webbläsaren blandar varje bildruta däremellan.

Den här tekniken ritar också om varje bildruta, precis som den första. Dess fördel är kontroll: du kan flytta ett sken i en mesh-gradient, rotera en konisk ram eller förskjuta en varumärkesgradient mot en andra palett utan några överdimensionerade bakgrunder.

Teknik 3: transformera ett gradientlager

Lägg gradienten på ett pseudoelement som är mycket större än elementet och animera dess transform, till exempel en långsam rotation eller drift. Webbläsare kan oftast flytta ett transformerat lager på grafikkortet utan att rita om det, så det här är det billigaste sättet att animera en stor gradient. will-change: transform antyder att lagret bör lyftas fram i förväg.

css
.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); }
}
En enorm konisk gradient som långsamt vrider sig bakom innehållet. Den negativa inset-marginalen håller hörnen täckta medan den roterar.

Teknik 4: tona mellan två gradienter

Stapla två gradientlager och animera opacity på det översta. Opacity är också en egenskap som sammanfogaren hanterar smidigt, så toningen är mjuk och billig. Den passar långsamma stämningsskiften, som en dagpalett som tonar över i en nattpalett, och låter de två gradienterna vara helt olika uppbyggda.

css
.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; }
}
Dag tonar över i natt och tillbaka. Bara opacity ändras, så inget ritas om.

Att välja teknik

TeknikWebbläsarens arbete per bildrutaBäst för
Flytta background-positionOmritningSmå element, knappar, text
@property-färger och vinklarOmritningExakta färgändringar, roterande ramar
transform på ett lagerOftast bara sammanfogningStora helskärmsbakgrunder
opacity-toningOftast bara sammanfogningLångsamma stämnings- eller palettskiften
Omritningar går bra på små ytor. För stora ytor är transform och opacity att föredra.

Mät i stället för att gissa. I Chrome DevTools markerar panelen Rendering med paint flashing de ytor som ritas om i varje bildruta, och en Performance-inspelning visar hur stor del av varje bildruta som går åt till ritning. CSS-gradienter och prestanda går igenom det.

Reducerad rörelse och god ton

Vissa blir yra eller distraherade av rörelse i bakgrunden, och operativsystemen låter dem be om mindre av den. Respektera det med en prefers-reduced-motion-fråga som stoppar animationen och lämnar en stillastående, färdig bild. Guiden om reducerad rörelse förklarar vad som räknas som rörelse värd att ta bort.

css
@media (prefers-reduced-motion: reduce) {
  .hero,
  .hero::before,
  .sky::after {
    animation: none;
  }
}
En regel som stoppar varje teknik ovan. Kontrollera att bilden som blir kvar fortfarande ser rätt ut.

Undvik

  • Cykler snabbare än cirka 8 sekunder på stora ytor
  • Regnbågsrotation av nyansen över hela sidan
  • Rörelse bakom brödtext som folk behöver läsa
  • Animationer som fortsätter köra när fliken står overksam i minuter

Gör så här

  • Långsam, stillsam rörelse inom en färgfamilj
  • Rörelse i hero, stillhet i innehållet
  • En lugn stillbild för reducerad rörelse
  • Testa på en enklare bärbar dator och telefon, inte bara en snabb stationär

Vanliga frågor

Kan man animera en CSS-gradient?

Inte direkt: webbläsare hoppar mellan två gradientvärden i keyframes. Animera i stället background-position, registrerade egna egenskaper som används i gradienten, eller transform och opacity på ett gradientlager.

Vad är det mjukaste sättet att animera en gradientbakgrund?

Att animera transform eller opacity på ett separat gradientlager, eftersom webbläsare oftast kan hantera de två utan att rita om.

Hur animerar jag gradientfärger i CSS?

Registrera varje färg med @property och syntax: "<color>", använd egenskaperna i gradienten och ändra dem i @keyframes.

Gör animerade gradienter en sida långsammare?

Små spelar sällan roll. Stora animerade bakgrunder som ritas om varje bildruta kan kosta batteri och mjukhet, så föredra transform eller opacity och mät med DevTools.

Hur respekterar jag reducerad rörelse i gradientanimationer?

Lägg en animation: none-regel i @media (prefers-reduced-motion: reduce) så att användare som ber om mindre rörelse ser en stillbild.

Dela den här guiden

Skriven av GradientlyVerifierat Gradiently-konto

Teamet bakom Gradiently, ett designverktyg byggt kring Marks: levande gradienter som får allt du gör att kännas som ditt.

Se vår profil