CSS og nett

CSS-støytekstur: legg korn på gradienter med SVG

Et svakt lag med støy skjuler banding og får flat skjermfarge til å føles som trykk eller film. Her er SVG-filteret bak det, justert og klart til å limes inn.

GradientlyVerifisert Gradiently-konto··4 min lesetid
Omslag: Muslin Anvil · GR·W4AX·4M

Kortversjonen

  • En CSS-støytekstur lages vanligvis med et SVG feTurbulence-filter, innebygd som et lite data-URI-bilde og flislagt over en gradient.
  • baseFrequency i feTurbulence styrer kornstørrelsen: høyere verdier gir finere korn, lavere verdier gir grov, skyet støy.
  • Støy fungerer best lagt over gradienten på et pseudoelement med en blandingsmodus som soft-light eller overlay og lav dekning.
  • Korn skjuler gradientbanding fordi det bryter de synlige kantene mellom nabotoner opp i fin, tilfeldig variasjon.
  • Et flislagt støybilde er billig å gjengi, mens et levende SVG-filter på et stort element, eller å animere det, koster langt mer.
På denne siden

En CSS-støytekstur er en fin, tilfeldig spraking lagt over en farge eller gradient for å gi den korn. CSS har ingen støyfunksjon, så den vanlige kilden er SVG: feTurbulence-filteret lager støy, du pakker det inn i en liten SVG, bygger den inn som en data-URI og fliser den over gradienten med lav styrke. Resultatet ser ut som filmkorn eller trykt papir, og det retter stille opp banding, den synlige trinndelingen som dukker opp i store, myke gradienter.

Hvorfor korn får farge til å se dyrere ut, står i kornete gradienter. Denne guiden er implementeringen.

SVG-støyfilteret

html
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240">
  <filter id="n">
    <feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="3" stitchTiles="stitch" />
    <feColorMatrix type="saturate" values="0" />
  </filter>
  <rect width="100%" height="100%" filter="url(#n)" />
</svg>
En flis på 240 piksler med grå støy. Lagre den som noise.svg, eller bygg den inn som vist under.
AttributtVerdi herHva det styrer
typefractalNoiseMykt, jevnt korn. turbulence gir stripete, krusete støy.
baseFrequency0.8Kornstørrelse. Rundt 0.6 til 0.9 er fint korn, og 0.1 til 0.3 er skyet.
numOctaves3Lag med detaljer. Utover omtrent 4 er forskjellen vanskelig å se.
stitchTilesstitchFår flisens kanter til å passe, så gjentakelser ikke har sømmer.
feColorMatrix saturate 00Fjerner den tilfeldige fargen og lar grått korn stå igjen.
Innstillingene som betyr noe. MDNs referanse for feTurbulence dokumenterer resten.

Å bygge inn støy som en data-URI

En egen fil fungerer, men å bygge den inn sparer en forespørsel og holder effekten på ett sted. I en data-URI må tegn som har betydning i URL-er kodes: < blir %3C, > blir %3E, # blir %23 og % blir %25. Bruk enkle anførselstegn inne i SVG-en så de ikke kolliderer med de doble rundt URL-en.

css
:root {
  --noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
Den samme flisen som en egendefinert egenskap du kan gjenbruke overalt. Å glemme å kode # som %23 er den vanlige grunnen til at den ikke viser noe i Firefox.

Å legge støy over en gradient

Legg støyen på et pseudoelement over gradienten, og styr den med to rattet: en blandingsmodus, som avgjør hvordan det grå kornet blandes med fargen under, og dekning, som avgjør hvor sterkt det er. soft-light holder fargene rene og er den mildeste, mens overlay gir mer kontrast. pointer-events: none hindrer laget i å blokkere klikk.

css
.grain {
  position: relative;
  isolation: isolate;
  background: linear-gradient(135deg, #1e1b4b, #7c3aed 55%, #f472b6);
}

.grain::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--noise);
  mix-blend-mode: soft-light;
  opacity: 0.45;
  pointer-events: none;
}
Korn mellom gradienten og innholdet: teksten inne i .grain forblir skarp.
Tre gradienter som vinner mest på korn. Mørke utfasinger med lav kontrast, som den i midten, er der banding vises først.

Foretrekker du ett enkelt element uten pseudoelement, list støyen først i background-image og sett background-blend-mode: soft-light, normal. Da mister du det egne dekningsrattet, så bak inn styrken i SVG-en i stedet, for eksempel med opacity='0.5' på rect.

Hvor mye korn er nok

  1. 1

    Start svakt

    Begynn på opacity: 0.3 med soft-light. Du bør knapt merke det på en armlengdes avstand.

  2. 2

    Sjekk det mørkeste området

    Banding bor i mørke, langsomme utfasinger. Øk dekningen til trinnene der løses opp, og stopp så.

  3. 3

    Tilpass kornet til størrelsen

    Fullskjerms heroer tåler litt grovere korn, rundt 0.6. Kort og knapper vil ha fint korn, rundt 0.9.

  4. 4

    Sjekk på en mobil og en stor skjerm

    Korn som ser riktig ut på én skjerm, kan ligne støv på en annen. Sikt mot tekstur du kjenner heller enn ser.

  5. 5

    Sjekk teksten oppå

    Korn må ikke redusere lesbarheten. Hvis liten tekst ligger på teksturen, senk styrken eller hold teksten på et roligere område.

For mye

  • Korn synlig fra andre siden av rommet
  • Farger blir grå og skitne
  • Grov, skyet støy på små komponenter
  • Tekstkanter ser uskarpe ut mot spraket

Omtrent riktig

  • Korn som bare merkes på nært hold
  • Farger holder seg rene med soft-light
  • Fint korn tilpasset elementet
  • Banding borte, tekst skarp

Ytelsen til CSS-støy

En flislagt data-URI er billig: nettleseren gjengir den lille flisen én gang og gjentar den, og et statisk lag males én gang. Den dyre versjonen er å bruke filteret levende på et stort element med filter: url(#noise), som kjører filteret over hver piksel hver gang området tegnes om. Hvis du animerer korn, for et flimrende filmpreg, flytt det flislagte laget med transform i noen få rykkende steg i stedet for å generere støy på nytt, og skru det av for redusert bevegelse.

css
.grain {
  overflow: hidden;
}

.grain::after {
  inset: -50%;
  animation: flicker 0.6s steps(3) infinite;
}

@keyframes flicker {
  0%   { transform: translate(0, 0); }
  33%  { transform: translate(-3%, 2%); }
  66%  { transform: translate(2%, -3%); }
}

@media (prefers-reduced-motion: reduce) {
  .grain::after { animation: none; }
}
Animert korn ved å flytte en overdimensjonert flis. Den negative innrykkingen holder kantene dekket mens den skifter.

En forhåndsgjengitt PNG- eller WebP-støyflis på rundt 128 til 256 piksler er en like god kilde hvis du allerede har en. Korn er også én ingrediens i en bredere familie av flater, fra papir til glass, omtalt i bakgrunnstekstur. Det er også sluttlaget på en mesh-gradient i CSS.

Korn er bygget inn i hver Gradiently-Mark som en materialinnstilling, ved siden av lys og bevegelse, så design laget med en har tekstur uten noen kode.

Muslin Anvil

GR·W4AX·4M

Muslin Anvil

Se denne Marken
En Mark med korn som del av materialet, gjengitt live i stedet for lagt på i etterkant.

Spørsmål folk stiller

Hvordan legger jeg til en støytekstur i CSS?

Bygg inn en SVG med et feTurbulence-filter som en data-URI, flis den på et pseudoelement over gradienten din, og sett en blandingsmodus som soft-light med lav dekning.

Hvorfor vises ikke SVG-støy-data-URI-en min?

Som regel et ukodet tegn. I data-URI-en koder du # som %23, % som %25 og vinkelparentesene som %3C og %3E, og bruker enkle anførselstegn inne i SVG-en.

Fikser korn gradientbanding?

Ja, i de fleste tilfeller. Tilfeldig fin variasjon bryter opp de harde kantene mellom nabotoner, så øyet ikke lenger ser trinn.

Hvilken baseFrequency bør jeg bruke til korn?

Rundt 0.6 til 0.9 gir fint, filmaktig korn. Lavere verdier som 0.2 gir stor, skyet støy.

Er CSS-støy dårlig for ytelsen?

Et lite flislagt støybilde er billig. Levende SVG-filtre på store elementer og støy som genereres på nytt hele tiden, er det som koster mest.

Del denne guiden

Skrevet av GradientlyVerifisert Gradiently-konto

Teamet bak Gradiently, et designverktøy bygget rundt Marks: levende gradienter som gjør at alt du designer ser ut som ditt.

Se profilen vår