CSS en web

CSS-ruistextuur: korrel aan kleurverlopen toevoegen met SVG

Een vage laag ruis verbergt banding en laat vlakke schermkleur aanvoelen als drukwerk of film. Dit is het SVG-filter erachter, afgesteld en klaar om te plakken.

GradientlyGeverifieerd Gradiently-account··5 min lezen
Cover: Muslin Anvil · GR·W4AX·4M

De korte versie

  • Een CSS-ruistextuur wordt meestal gemaakt met een SVG feTurbulence-filter, ingebed als kleine data-URI-afbeelding en over een kleurverloop getegeld.
  • De feTurbulence baseFrequency bepaalt de korrelgrootte: hogere waarden geven fijnere korrel, lagere waarden grove, wolkerige ruis.
  • Ruis werkt het best over het kleurverloop gelegd op een pseudo-element met een mengmodus als soft-light of overlay en een lage opacity.
  • Korrel verbergt kleurverloopbanding omdat ze de zichtbare randen tussen naburige tinten opbreekt in fijne, willekeurige variatie.
  • Een getegelde ruisafbeelding is goedkoop om te renderen, terwijl een live SVG-filter op een groot element toepassen, of animeren, veel meer kost.
Op deze pagina

Een CSS-ruistextuur is een fijne, willekeurige spikkeling over een kleur of kleurverloop die hem korrel geeft. CSS heeft geen ruisfunctie, dus de standaardbron is SVG: het filter feTurbulence genereert ruis, je verpakt het in een piepkleine SVG, bedt die in als data-URI en tegelt hem met lage sterkte over je kleurverloop. Het resultaat lijkt op filmkorrel of gedrukt papier, en verhelpt stilletjes banding, de zichtbare trapvorming die in grote, gladde kleurverlopen verschijnt.

Waarom korrel kleur duurder laat ogen staat in korrelige kleurverlopen. Deze gids is de implementatie.

Het SVG-ruisfilter

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>
Een tegel van 240 pixels grijze ruis. Bewaar hem als noise.svg, of bed hem in zoals hieronder.
KenmerkWaarde hierWat het stuurt
typefractalNoiseZachte, gelijkmatige korrel. turbulence geeft strepigere, rimpelende ruis.
baseFrequency0.8Korrelgrootte. Rond 0,6 tot 0,9 is fijne korrel; 0,1 tot 0,3 is wolkerig.
numOctaves3Lagen detail. Boven ongeveer 4 is het verschil moeilijk te zien.
stitchTilesstitchLaat de randen van de tegel op elkaar aansluiten, zodat herhalingen geen naden hebben.
feColorMatrix saturate 00Haalt de willekeurige kleur weg en laat grijze korrel over.
De instellingen die tellen. De MDN-referentie voor feTurbulence documenteert de rest.

Ruis inbedden als data-URI

Een apart bestand werkt, maar inbedden bespaart een verzoek en houdt het effect op één plek. In een data-URI moeten tekens die in URL’s iets betekenen worden gecodeerd: < wordt %3C, > wordt %3E, # wordt %23 en % wordt %25. Gebruik enkele aanhalingstekens binnen de SVG zodat ze niet botsen met de dubbele rond de URL.

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");
}
Dezelfde tegel als aangepaste eigenschap die je overal kunt hergebruiken. Vergeten # als %23 te coderen is de gebruikelijke reden dat er niets verschijnt in Firefox.

Ruis over een kleurverloop leggen

Zet de ruis op een pseudo-element boven het kleurverloop en stuur het met twee knoppen: een mengmodus, die bepaalt hoe de grijze korrel met de kleur eronder mengt, en opacity, die bepaalt hoe sterk het is. soft-light houdt kleuren schoon en is de zachtste; overlay voegt meer contrast toe. pointer-events: none voorkomt dat de laag klikken blokkeert.

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;
}
Korrel tussen het kleurverloop en de inhoud: de tekst in .grain blijft scherp.
Drie kleurverlopen die het meest winnen met korrel. Donkere overgangen met laag contrast, zoals de middelste, zijn waar banding het eerst zichtbaar is.

Geef je de voorkeur aan één element zonder pseudo-element, zet dan de ruis eerst in background-image en stel background-blend-mode: soft-light, normal in. Je verliest de aparte opacity-knop, dus bak de sterkte in de SVG in, bijvoorbeeld met opacity='0.5' op de rect.

Hoeveel korrel is genoeg

  1. 1

    Begin vaag

    Begin bij opacity: 0.3 met soft-light. Je zou het op armlengte nauwelijks moeten merken.

  2. 2

    Controleer het donkerste vlak

    Banding zit in donkere, trage overgangen. Verhoog de opacity tot de trappen daar oplossen en stop dan.

  3. 3

    Stem de korrel af op de grootte

    Heroes over het hele scherm verdragen iets grovere korrel, rond 0,6. Kaarten en knoppen willen fijne korrel, rond 0,9.

  4. 4

    Controleer op een telefoon en een groot beeldscherm

    Korrel die op het ene scherm goed lijkt kan op een ander op stof lijken. Mik op textuur die je voelt in plaats van ziet.

  5. 5

    Controleer de tekst erbovenop

    Korrel mag de leesbaarheid niet verminderen. Staat kleine tekst op de textuur, verlaag dan de sterkte of houd tekst op een rustiger vlak.

Te veel

  • Korrel zichtbaar van de andere kant van de kamer
  • Kleuren worden grijs en vies
  • Grove, wolkerige ruis op kleine componenten
  • Tekstranden zien er wazig uit tegen de spikkeling

Ongeveer goed

  • Korrel die je alleen van dichtbij opmerkt
  • Kleuren blijven schoon met soft-light
  • Fijne korrel afgestemd op het element
  • Banding weg, tekst scherp

Prestaties van CSS-ruis

Een getegelde data-URI is goedkoop: de browser rendert de kleine tegel één keer en herhaalt hem, en een statische laag wordt één keer getekend. De dure versie is het filter live op een groot element toepassen met filter: url(#noise), wat het filter over elke pixel laat lopen wanneer het vlak opnieuw wordt getekend. Animeer je korrel, voor een flikkerende filmlook, verschuif dan de getegelde laag met transform in een paar schokkerige stappen in plaats van ruis opnieuw te genereren, en zet hem uit voor verminderde beweging.

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; }
}
Geanimeerde korrel door een te grote tegel te verplaatsen. De negatieve inset houdt de randen bedekt terwijl hij verschuift.

Een vooraf gerenderde PNG- of WebP-ruistegel van ongeveer 128 tot 256 pixels is een even goede bron als je er al een hebt. Korrel is ook één ingrediënt van een bredere familie oppervlakken, van papier tot glas, behandeld in achtergrondtextuur. Het is ook de afwerkende laag op een CSS mesh gradient.

Korrel zit in elke Mark van Gradiently ingebouwd als materiaalinstelling, naast licht en beweging, dus ontwerpen die ermee zijn gemaakt dragen textuur zonder code.

Muslin Anvil

GR·W4AX·4M

Muslin Anvil

Bekijk deze Mark
Een Mark met korrel als onderdeel van zijn materiaal, live gerenderd in plaats van achteraf gelaagd.

Vragen die mensen stellen

Hoe voeg ik een ruistextuur toe in CSS?

Bed een SVG met een feTurbulence-filter in als data-URI, tegel hem op een pseudo-element over je kleurverloop en stel een mengmodus als soft-light in met lage opacity.

Waarom verschijnt mijn SVG-ruis-data-URI niet?

Meestal een niet-gecodeerd teken. Codeer in de data-URI # als %23, % als %25 en de punthaken als %3C en %3E, en gebruik enkele aanhalingstekens binnen de SVG.

Verhelpt korrel kleurverloopbanding?

In de meeste gevallen wel. Willekeurige fijne variatie breekt de harde randen tussen naburige tinten op, zodat het oog geen trappen meer ziet.

Welke baseFrequency moet ik voor korrel gebruiken?

Rond 0,6 tot 0,9 geeft fijne filmachtige korrel. Lagere waarden zoals 0,2 geven grote, wolkerige ruis.

Is CSS-ruis slecht voor de prestaties?

Een kleine getegelde ruisafbeelding is goedkoop. Live SVG-filters op grote elementen en steeds opnieuw gegenereerde ruis kosten het meest.

Deel deze gids

Geschreven door GradientlyGeverifieerd Gradiently-account

Het team achter Gradiently, een ontwerptool rond Marks: levende kleurverlopen die alles wat je ontwerpt op jou laten lijken.

Bekijk ons profiel