Filter in SVG/Standardfilter

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

In Arbeit, noch unverlunken

SVG-Filter (die in den nächsten Kapiteln ausführlicher erklärt werden) bieten zwar viele Möglichkeiten, werden aber auch schnell komplex in der Anwendung und im Markup.

Deshalb sind häufig benötigte Filter-Algorithmen als CSS-Funktionen vorgefertigt und können in SVG im filter-Attribut sowie im CSS in den filter- und backdrop-filter-Eigenschaften verwendet werden. Sie sind zwar nicht ganz so leistungsfähig wie ihre SVG-Eltern, aber bequem und leicht verständlich und bieten einen einfachen Ansatz zum Erreichen gängiger Effekte, wie z. B. Weichzeichnen. Ein weiterer Vorteil ist, dass sie auf einfache Weise mit CSS animiert werden können.

Hinweis:
Die vordefinierten CSS-Filter können prinzipiell auch als SVG-Filtereffekte selbt erstellt werden. Das muss man nicht selbt erfinden, die Filter Effects Spezifikation enthält alle Filterdefinitionen. Leider passt das nicht immer ganz, der blur()-Filter verhält sich beispielsweise etwas anders als der <feGaussianBlur>-Filtereffekt.

Weichzeichner

Der blur()-Filter wendet einen Gaußschen Weichzeichner[1] auf die Grafik (oder den Text) an.

Syntax:

   blur(radius)

Der Filter erwartet als Radius eine Längenangabe, erlaubt aber keine Prozentwerte. Die übergebene Länge wird allerdings nicht als Radius für den Wirkungsbereich des Weichzeichners verwendet, sondern, wie bei dem zu Grunde liegenden SVG/Element/feGaussianBlur-Urfilter, als Standardabweichung. Dies ist in etwa der Radius, aus dem um das jeweilig bearbeitete Pixel herum Nachbarpixel in die Weichzeichnung eingehen, aber nicht genau.

Beispiel ansehen …
.blur {
  filter: blur(0.08em);  
}
Beachte: Der Gaußsche Weichzeichner bildet für jedes Pixel einen Mittelwert der Farbwerte im Umkreis. Der Anteil des Umkreispixels am Mittelwert wird dabei durch die Gaußsche Glockenkurve bestimmt. Die Anzahl der verarbeiteten Pixel wächst mit dem Quadrat der Standardabweichung und damit wird die Berechnung schnell aufwändig. Sei also vorsichtig, bevor Du einen aufwändigen Filter auf die Welt loslässt.

Auch der dropshadow-Filter verwendet den Weichzeichner, sodass man bei den Werten für radius und spread die benötigte Rechenzeit berücksichtigen muss.

Empfehlung: Wenn du einen Weichzeichner verwendest, halte die Werte für den Radius so gering wie möglich, um eine verzögerte Darstellung auf langsameren Geräten zu vermeiden. Teste deine Seite möglichst auf langsamer Hardware, bevor Du sie online stellst.

Helligkeit

Der brightness ()-Filter ändert die Helligkeit der Grafik, indem er Pixel für Pixel den Rot-, Grün- und Blauwert mit dem angegebenen Faktor multipliziert.

Syntax:

   brightness(faktor)

Der Filter erfordert eine Angabe eines Prozentwerts oder einer positiven Zahl; Prozentangaben werden zuerst durch 100 dividiert und dann als Zahl verwendet. Ein Wert von 0 ergibt schwarz, 1 ist die normale Helligkeit, 2 erzielt doppelte Helligkeit. Ist das Ergebnis für einen Farbkanal größer als 255, wird es auf 255 limitiert.

Beispiel ansehen …
.dunkler {
  filter: brightness(.5);  
}
.heller {
  filter: brightness(1.5);  
}
.nochHeller {
  filter: brightness(2.5);  
}

Der brightness-Filter muss immer nur ein Pixel verarbeiten. Seine Geschwindigkeit hängt deshalb nicht vom angegebenen Faktor ab.

Empfehlung: Wenn du mehr über die Burg aus dem Beispiel erfahren willst, stöber' doch durch unsere SVG-Doku.

Kontrast

Der contrast()-Filter regelt den Kontrast, das ist der Unterschied zwischen den dunkelsten und hellsten Farben.

Syntax:

  contrast(faktor)

Der Filter erfordert eine Angabe eines Prozentwerts oder einer positiven Zahl; ein Wert von 0 ergibt schwarz, 1 ist der normale Kontrast, ein höherer Wert erhöht den Unterschied zwischen den Farben weiter.

Beispiel ansehen …
.weniger {
  filter: contrast(.5);  
}
.höher {
  filter: contrast(1.5);  
}
.nochHöher {
  filter: contrast(2.5);  
}

Der Kontrastfilter hat das gleiche Laufzeitverhalten wie der Helligkeitsfilter.

Schlagschatten

Der drop-shadow()-Filter erzeugt einen Schlagschatten, optional mit Hilfe eines Gaußschen Unschärfefilters. Die nicht-transparenten Teile des Elements (genauer: der Alpha-Kanal des angezeigten Inhalts) werden einheitlich gefärbt und erhalten mit Hilfe der Gaußschen Unschärfe einen verschwommenen Rand. Das Ergebnis wird um einen Offset verschoben und (in der Z-Achse) hinter dem Element dargestellt.

Syntax:

  drop-shadow( farbe offset-x offset-y [stdDev] )
  drop-shadow( offset-x offset-y [stdDev] farbe )
offset-x und offset-y

sind eine Längenangabe und legen fest, um wieviel der Schatten gegenüber dem schattierten Element verschoben werden soll.

stdDev
ist der – optionale – Standardabweichungs-Parameter für den Unschärfefilter. Fehlt er oder wird er auf 0 gesetzt, ist der Schatten scharfkantig.
farbe
die Farbe, die der Schatten besitzen soll. Dieser Parameter kann als erstes oder als letztes angegeben werden.

Damit ähnelt drop-shadow() der box-shadow-Eigenschaft. Es gibt aber deutliche Unterschiede im Ergebnis:

  • box-shadow berücksichtigt keine transparenten Anteile des schattierten Elements, sondern erzeugt einen Schlagschatten in Form des Begrenzungsrahmens des Elements. Und selbst wenn das Element transparenten Hintergrund hat, bleibt der Schlagschatten hinter dem Element-Rechteck unsichtbar.
  • Der drop-shadow()-Filter wird auf die gerenderten Pixel angewendet – das bedeutet, dass die sichtbaren Teile des Elements einschließlich der Transparenz berücksichtigt werden.
Vergleich box-shadow vs drop-shadow() ansehen …
.box-shadow {
  box-shadow: 20px 20px 10px rgb(0 0 0 /0.4);
}

.drop-shadow-1 {
  filter: drop-shadow(10px 10px 10px rgb(0 0 0 /0.4));
}

.drop-shadow-2 {
  filter: drop-shadow(10px 80px 0px rgb(0 0 0 /0.5));
}

Der Schatten passt sich den Umrissen des Flugzeugs an. Dies ist mit box-shadow nicht möglich.

Beachte: Der Safari hat bis heute (Stand: Oktober 2025) einen Bug, der drop-shadow() bei SVG-Elementen nicht rendert.
Eine Lösung ist es, in Webseiten nur das zu schattierende Element in ein gesondertes SVG zu geben und den Schatten auf das SVG-Element zu legen.

Graustufen

Der grayscale()-Filter reduziert die Farbsättigung und wandelt im Extremfall (wirkstärke=1) das Bild in Graustufen um. Die verwendete Berechnungsformel berücksichtigt die WCAG-Formel zur Berechnung der Luminanz und sorgt dafür, dass die wahrgenommene Helligkeit der Bildpunkte gleich bleibt.

Syntax:

  grayscale( wirkstärke )

Der Filter erfordert die Angabe der Wirkstärke als positive Zahl von 0 bis 1, alternativ kann die Wirkstärke auch in Prozent angegeben werden (und wird dann in 0 bis 1 umgerechnet). Eine Wirkstärke von 0 lässt das Bild unverändert, 1 ergibt grau, Dezimalwerte dazwischen reduzieren die Farbsättigung entsprechend. Innerhalb des erlaubten Bereichs für die Wirkstärke w führt die Anwendung von grayscale(w) und saturate(1-w) (bzw. saturate 100%-w)) zum gleichen Ergebnis.

Beispiel ansehen …
.angegraut {
  filter: grayscale(0.5);  /* Als Zahl, entspricht 50% */
}
.angegrauter {
  filter: grayscale(75%);  /* Als Prozentwert, entspricht 0.75 */
}
.grau {
  filter: grayscale(100%);  
}

Siehe auch:

  • Schieberegler (der die Farbwerte eines Bildes stufenlos ändert)

Änderung des Farbtons

Der hue-rotate()-Filter wendet eine Farbtonrotation (im HSL-Modell) auf das Ursprungsbild an.

Syntax:

  hue-rotate( farbwinkel )
farbwinkel
Winkelmaß-Angabe für die Farbtonänderung. Ein Farbwinkel von 0deg lässt das Bild unverändert.

Der Farbton jedes Bildpunktes wird um den angegebenen Winkel verändert und die Helligkeit dabei so angeglichen, dass die Bildpunkthelligkeit in etwa erhalten bleibt. Dazu wird die WCAG-Luminanzformel zu Grunde gelegt.

Beispiel ansehen …
.viertel {
  filter: hue-rotate(90deg);  
}
.halb {
  filter: hue-rotate(180deg);
}
.dreiviertel {
  filter: hue-rotate(270deg);  
}

Farbumkehr

Der invert()-Filter kehrt die Farben des Ursprungsbilds um.

Syntax:

   invert( wirkstärke )
Abbildungskurven für invert-Funktion
wirkstärke
Zahl von 0 bis 1 oder Prozentangabe von 0% bis 100%. Ein Wert von 0 oder 0% lässt das Bild unverändert, mit 1 oder 100% werden die Farben vollständig invertiert.

Invertieren bedeutet hier, dass für jeden Farbkanal der jeweilige Kanalwert umgerechnet wird. Die Wirkstärke w bestimmt den Verlauf der Abbildungsgerade. Der Farbwert 0 wird auf 255×w abgebildet, der Farbwert 255 auf 255×(1-w), die übrigen Werte entsprechend dem Verlauf der Verbindungsstrecke. Das Bild zeigt unterschiedliche Abbildungsverläufe, je nach eingestellter Wirkstärke. Deswegen bewirkt invert(0) nichts, es bildet (0 bis 255) auf (0 bis 255) ab. Mit invert(1) wird hingegen der Bereich (0 bis 255) auf (255 bis 0) abgebildet, ein Rotwert von 0 würde zu 255 und ein Rotwert von 200 würde zu 55.

Daraus ergibt sich auch, dass invert(0.5) eine einheitliche graue Fläche erzeugt, denn alle Farbkanalwerte werden auf das Intervall (127.5 bis 127.5) abgebildet – alle Farben werden zu #7F7F7F.

Beispiel ansehen …
.wenig {
  filter: invert(0.25);  
}
.mehr {
  filter: invert(0.75);
}
.nochmehr {
  filter: invert(1);  
}
Beachte: Ein Wert von 0.5 lässt das gesamte Bild grau erscheinen.

Automatisch kontrastreiche Schriftfarbe

Durch geschickte Kombination mehrerer Filter kann man Text je nach Hintergrundhelligkeit schwarz oder weiß einfärben, ohne die Komponenten in HSL oder oklch() aufzulösen:

Schwarz oder Weiß? ansehen …
span {
	color: var(--bgColor);
	filter: invert(1) grayscale(1) brightness(1.3) contrast(9000);
	mix-blend-mode: luminosity;
	opacity: 0.95;
}

Dies wird um #AAAAAA herum schwarz. Stelle die Helligkeit niedriger ein, wenn du willst, dass es früher schwarz wird. Spiel auch mit dem Kontrast herum, indem du niedrige und hohe Werte verwendest.[2]

Deckkraft

Der opacity()-Filter regelt die Deckkraft, oder vielmehr die Transparenz eines Bilds.

Der Filter erfordert eine Angabe eines Prozentwerts oder einer positiven Zahl; ein Wert von 1 lässt das Bild im Normalzustand; 0 ist komplett durchsichtig.

Beispiel ansehen …
.wenig {
  filter: opacity(0.75);  
}
.mehr {
  filter: opacity(0.5);
}
.nochmehr {
  filter: opacity(0.25);  
}


Sättigung

Der saturate()-Filter regelt die Farbsättigung eines Bildes.

Der Filter erfordert eine Angabe eines Prozentwerts oder einer positiven Zahl; ein Wert von 1 lässt das Bild im Normalzustand; höhere Werte erhöhen die Sättigung.

Beispiel ansehen …
.wenig {
  filter: saturate(2);  
}
.mehr {
  filter: saturate(4);
}
.nochmehr {
  filter: saturate(8);  
}


Sepiatönung

Der sepia()-Filter konvertiert das Ursprungsbild in Sepiafarben, sodass es wie ein vergilbtes altes Schwarzweiß-Bild aussieht.

Der Filter erfordert eine Angabe eines Prozentwerts von 0-100% oder einer positiven Zahl von 0-1; ein Wert von 0 lässt das Bild unverändert, 1 ergibt eine sepia-Tönung, die Werte dazwischen reduzieren die Farbwerte entsprechend.

Beispiel ansehen …
.wenig {
  filter: sepia(0.33);
}
.mehr {
  filter: sepia(0.66);
}
.nochmehr {
  filter: sepia(1);
}

Animationen mit Filtern

Durch die Kombination mit CSS-animation kann man interessante Effekte erzielen.

glow-Animation

Neonschilder ansehen …
.svg-shadow {
  animation: svg-shadow 2s  infinite alternate;
}

@keyframes svg-shadow {
  from {
    filter: drop-shadow( 0 0 0 #fff) drop-shadow( 0 0 0 #e60073) drop-shadow( 0 0 0 #e60073);
  }

  to {
    
    filter: drop-shadow( 0 0 20px #fff) drop-shadow( 0 0 25px #e60073) drop-shadow( 0 0 40px #e60073);
  }
}

color-burn Animation

Beispiel ansehen …
img { 
  animation: filter-animation 5s infinite;
}

@keyframes filter-animation {
  0% {
    filter: sepia(0) saturate(2);
  }
  
  50% {
    filter: sepia(1) saturate(8);
  }
  
  100% {
    filter: sepia(0) saturate(2);
  }
}

backdrop-filter

Die backdrop-filter-Eigenschaft wendet grafische Effekte wie Unschärfe oder Farbverschiebung auf den Bereich hinter einem Element an. Da der Effekt auf alles hinter dem Element angewendet wird, muss das Element oder sein Hintergrund transparent oder teilweise transparent sein, um den Effekt zu sehen.


Bildunterschrift mit verschwommenem Hintergrund ansehen …
.stacked figcaption {
	align-self: end;
	align-self: end;
	backdrop-filter: invert(30%);
	color: #fea;
	text-align: center;
}

In diesem Beispiel aus unserem Grid-Tutorial werden alle Kindelemente des figure-Elements übereinander gestapelt.

Die Figcaption wird mit align-self: end; nach unten positioniert und entsprechend dem Hintergrund hellgelb eingefärbt. Zusätzlich wurde der Hintergrund mit backdrop-filter etwas unscharf gestellt, damit die Bildunterschrift besser lesbar ist.

Siehe auch

  • Buttons mit CSS gestalten

    Frosted Glass im Apple Look
    Sauberes CSS ohne Chaos:
    Gestaltung mit Variablen und SPOT

Referenz zu einem SVG <filter> Element

Anstelle der vordefinierten CSS-Filter kann man auch komplexere SVG-Filter einbinden.


Beispiel ansehen …
img { 
  filter: url('#KantenErkennung');
}
  <figure>
    <img src="Lauf-3.jpg" width="450" height="450" alt="Lauf" >
    <figcaption>Einbindung von SVG-Filter</figcaption>
  </figure>

<svg>
  <defs>
      <filter id="KantenErkennung">
      <feConvolveMatrix 
        order="3"
        preserveAlpha="true" 
        kernelMatrix="
		  -1 -1 -1
		  -1  8 -1
		  -1 -1 -1"
		divisor="1.0"
		bias="0.0"   
		  />
    </filter>
  </defs>
</svg>

Die CSS-Festlegung verweist auf einen Filter mit der id KantenErkennung. Dieser SVG-Filter wird in einem SVG-Fragment am Ende des Seiteninhalts in das HTML-Dokument integriert.

Das SVG-Fragment beinhaltet einen Definitionsabschitt mit einem feConvolveMatrix-Filter, der die Kanten der Farben deutlich zu Tage treten lässt.


Siehe auch

  • Filter-Effekte mit SVG-Text
  • Vermischen mit Blend-Modes
    HTML-CSS-JS.svg

Weblinks

  1. Wikipedia: Gaußscher Weichzeichner
  2. https://bildung.social/@miunau@meow.social/111911373742374167