CSS och webb

SVG-gradienter: linjära, radiella, konturer, text och masker

SVG har ett eget gradientsystem, äldre än CSS-gradienter och med förmågor de saknar: färga en kontur, fylla ett ord, dela en gradient mellan många former och tona ut vad som helst med en mask.

GradientlyVerifierat Gradiently-konto··5 minuters läsning
Omslag: Cold Salon · GR·4AB2·SW

Kortversionen

  • En SVG-gradient definieras en gång som ett linearGradient- eller radialGradient-element med stop-barn, får ett id och används genom att fill eller stroke sätts till url(#id).
  • Som standard använder SVG-gradienters koordinater objectBoundingBox-enheter, där 0 och 1 är kanterna på formen som målas.
  • gradientUnits="userSpaceOnUse" placerar gradienten i teckningens egna koordinater, vilket låter en gradient sträcka sig över flera former och fixar gradienter på helt raka linjer.
  • spreadMethod avgör vad som händer bortom gradientens ändar: pad håller ändfärgerna, reflect speglar blandningen och repeat startar om den.
  • En SVG-mask använder ljushet, så en gradient från vitt till svart i en mask tonar ut det den läggs på.
På den här sidan

En SVG-gradient är en färg du definierar en gång och lägger på vilken form, linje eller text som helst i en SVG. Du skriver ett <linearGradient>- eller <radialGradient>-element i <defs>, ger det <stop>-barn för färgerna och ett id, och sätter sedan en forms fill eller stroke till url(#id). Till skillnad från en CSS-bakgrund kan den färga en kontur eller ett enskilt ord, och den skalas med teckningen.

html
<svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="dusk" x1="0" y1="0" x2="1" y2="1">
      <stop offset="0" stop-color="#1e1b4b" />
      <stop offset="0.55" stop-color="#7c3aed" />
      <stop offset="1" stop-color="#f472b6" />
    </linearGradient>
  </defs>
  <rect width="200" height="120" rx="16" fill="url(#dusk)" />
</svg>
En diagonal gradient på en rektangel med rundade hörn. x1, y1, x2 och y2 drar gradientens linje från övre vänstra till nedre högra hörnet.
Samma blandning, som CSSlinear-gradient(135deg, #1e1b4b 0%, #7c3aed 55%, #f472b6 100%)
SVG-koden ovan och den här CSS-gradienten stämmer överens på en kvadrat. På en rektangel sträcks SVG-versionen med formen; se gradientUnits nedan.

linearGradient och dess stopp

x1, y1, x2 och y2 anger start och slut för gradientens linje. Varje <stop> har en offset från 0 till 1 (eller 0 % till 100 %), en stop-color och en valfri stop-opacity. stop-color är också en CSS-egenskap, så du kan tematisera gradienter från en stilmall, till exempel stop { stop-color: var(--accent); }.

AttributStandardVad det gör
x1 y1 x2 y20 0 1 0, vänster till högerStart- och slutpunkter för gradientlinjen
gradientUnitsobjectBoundingBoxOm koordinaterna är relativa till formen eller till teckningen
spreadMethodpadVad som händer bortom ändarna: pad, reflect eller repeat
gradientTransformingenRotera, skala eller skeva gradienten, till exempel rotate(30)
hrefingenÄrv stopp och inställningar från en annan gradient
De viktigaste attributen hos linearGradient. radialGradient delar alla utom den första raden.

href sparar upprepning. Definiera dina stopp en gång i en basgradient och skapa sedan varianter som pekar på den och bara ändrar riktning eller enheter. MDN:s referens för linearGradient tar upp varje attribut.

radialGradient: centrum, radie och fokuspunkt

En radiell gradient har ett centrum (cx, cy) och en radie (r), som alla har standardvärdet 0,5, så den fyller formen från mitten. Den har också något CSS saknar: en separat fokuspunkt (fx, fy) där den första färgen börjar. Flyttar du fokuspunkten från mitten ser en sfär ut att vara belyst från ena sidan.

html
<radialGradient id="orb" cx="0.5" cy="0.5" r="0.5" fx="0.32" fy="0.28">
  <stop offset="0" stop-color="#e0f2fe" />
  <stop offset="0.45" stop-color="#0ea5e9" />
  <stop offset="1" stop-color="#082f49" />
</radialGradient>

<circle cx="60" cy="60" r="50" fill="url(#orb)" />
En fokuspunkt uppåt och åt vänster förvandlar en platt cirkel till en glansig sfär.
Belyst sfär, approximerad i CSSradial-gradient(circle at 32% 28%, #e0f2fe, #0ea5e9 35%, #082f49 80%)
CSS kan flytta centrum men inte skilja centrum från fokus, så det här är bara en approximation av SVG-klotet. Jämför radiella gradienter i CSS.

gradientUnits: objectBoundingBox eller userSpaceOnUse

Med standardvärdet objectBoundingBox betyder 0 och 1 kanterna på den form som målas, så varje form får hela gradienten, utsträckt så att den passar. Med userSpaceOnUse anges koordinaterna i SVG:ns egna enheter, så gradienten ligger kvar och formerna visar den del de täcker. Så kan en rad stapler dela en enda sammanhängande gradient.

objectBoundingBox

  • Koordinater från 0 till 1 över varje form
  • Varje form visar hela gradienten
  • Gradienten sträcks med formens proportioner
  • Fungerar inte på en helt horisontell eller vertikal linje

userSpaceOnUse

  • Koordinater i teckningens egna enheter
  • Formerna visar sin del av en gradient
  • Vinklarna förblir sanna oavsett form
  • Fungerar på raka linjer och tunna konturer

Gradienter på konturer och text

stroke="url(#id)" målar konturer, och så ritas gradientikoner, förloppsringar och diagramlinjer. På <text> färgar fill="url(#id)" bokstäverna, och orden förblir markerbara och sökbara. Lägg till en enfärgad reserv efter adressen, till exempel fill="url(#dusk) #7c3aed", så används den om gradienten inte hittas.

html
<svg viewBox="0 0 320 120" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="line" gradientUnits="userSpaceOnUse" x1="20" y1="0" x2="300" y2="0">
      <stop offset="0" stop-color="#22d3ee" />
      <stop offset="1" stop-color="#a855f7" />
    </linearGradient>
  </defs>
  <path d="M20 90 C 90 20, 160 110, 300 30" fill="none" stroke="url(#line)" stroke-width="6" stroke-linecap="round" />
  <text x="20" y="115" font-size="20" font-weight="700" fill="url(#line) #7c3aed">Growth</text>
</svg>
En gradient i teckningens enheter, delad av en kurva och ett ord. Båda går från cyan till lila över samma horisontella sträcka.

För gradientbokstäver i HTML i stället för SVG är gradienttext i CSS oftast enklare. Ta SVG-text när orden är en del av en illustration eller logotyp, eller ska följa en bana.

spreadMethod: pad, reflect och repeat

När gradientens linje är kortare än formen avgör spreadMethod vad som fyller resten. pad håller ändfärgerna, reflect speglar blandningen fram och tillbaka och repeat startar om den med en hård kant. Här går varje gradient från 30 % till 70 % av bredden.

Blågrönt till sand med de tre spridningsmetoderna, återgivna i CSS så att du kan jämföra dem sida vid sida.

Toning med SVG-masker

En mask använder ljushet: vita ytor visar det som maskeras, svarta ytor döljer det och grått är något däremellan. En gradient från vitt till svart i en <mask> tonar därför mjukt ut vilken form eller bild som helst till ingenting, och så mjukar du upp kanten på ett foto eller får en diagramlinje att tona bort i början.

html
<defs>
  <linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
    <stop offset="0.4" stop-color="#fff" />
    <stop offset="1" stop-color="#000" />
  </linearGradient>
  <mask id="soft-bottom">
    <rect width="100%" height="100%" fill="url(#fade)" />
  </mask>
</defs>

<image href="photo.jpg" width="100%" height="100%" mask="url(#soft-bottom)" />
Fotot syns helt upptill och tonar ut över de nedre 60 %.

För HTML-element gör CSS mask-image: linear-gradient(#000 40%, transparent) samma jobb, med alfa i stället för ljushet. Maskningstekniken används också för genomskinliga CSS-gradientkanter.

Undvik

  • Att återanvända samma gradient-id i två inbäddade SVG:er på en sida
  • Att dölja en sprite med gradientdefinitioner med display: none
  • Standardenheter på raka linjer
  • Mycket långa, mjuka, mörka gradienter utan struktur

Gör så här

  • Unika id:n, eller en delad sprite med definitioner
  • Dölj sprites med noll bredd och höjd i stället
  • userSpaceOnUse för konturer och delade gradienter
  • Lägg till korn på stora toningar, se CSS-brustextur

Vanliga frågor

Hur lägger jag till en gradient i en SVG?

Definiera en <linearGradient> eller <radialGradient> med <stop>-barn och ett id i <defs>, och sätt sedan en forms fill eller stroke till url(#id).

Varför syns inte min SVG-gradientkontur på en linje?

En rak horisontell eller vertikal linje har en avgränsningsruta utan storlek, så standardenheterna objectBoundingBox fungerar inte. Använd gradientUnits="userSpaceOnUse" med riktiga koordinater.

Hur roterar jag en SVG-gradient?

Ändra x1, y1, x2 och y2, eller lägg till gradientTransform="rotate(45 0.5 0.5)" för att rotera runt mitten av avgränsningsrutan.

Kan jag ändra SVG-gradientens färger med CSS?

Ja. stop-color och stop-opacity är CSS-egenskaper, så regler som stop { stop-color: var(--accent); } fungerar på inbäddad SVG.

Varför försvann min SVG-gradient när jag dolde SVG:n?

Definitioner i en SVG med display: none kanske inte ritas. Dölj spriten med noll bredd och höjd, eller med absolut position, i stället.

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