SVG CSS style und Stil-Attribute

SVG Style Regeln und stylen mit SVG Attributen und / oder CSS Superman und Batman

Das Aussehen von SVG-Formen kann durch Attribute wie fill, stroke, stroke-width, opacity, font-family variiert werden. Alternativ und ergänzend wirkt in SVG auch das style-Attribut genauso wie in HTML-Tags.

CSS in SVG

SVG hat viele Stile mit HTML gemeinsam. Attribute wie fill und stroke können auch in einem style-Attribut zusammengeführt werden. Es gibt also mehr als einen Weg, das Aussehen einer Form zu ändern:

  1. Mit einem regulären SVG-Attribut (fill = #fff)
  2. Mit CSS-Eigenschaften im style-Attribut des SVG-Tags (style="fill:#fff")
  3. Mittels class- und id-Attributen im SVG-Tag (<rect class="box" />)
  4. Durch Einbinden einer CSS-Datei (<?xml-stylesheet type="text/css" href="svg-style.css" ?>)
  5. Last, but not least: Media Queries für Breakpoints wirken auch in SVG

Genauso wie in HTML-Dateien kann ein style-Tag alle CSS-Eigenschaften der SVG-Elemente aufführen. Auch wenn das SVG inline ins Markup gesetzt wird, hat der Validator nichts daran auszusetzen.

SVG-Attribute

Attribute für die Positionierung und die Größe der Form selber haben keine Entsprechung durch eine CSS-Eigenschaft. Das sind die Attribute für die Position x und y bzw. cx und cy, r für den Radius und rx für abgerundete Ecken von Rechtecken, width und height und das d-Attribut von Pfaden.

fill entspricht einerseits background-color bei Formen, bei Text entspricht fill der CSS-Eigenschaft color.

CSS border gibt es nicht in SVG, sondern hier heißt es stroke für die Farbe des Rahmens und die Breite des Rahmens wird durch stroke-width festgelegt – entweder als Attribut oder als CSS-Eigenschaft.

x / y
keine Entsprechung
r
keine Entsprechung
width / height
keine Entsprechung
cx /cy
keine Entsprechung
rx / ry
keine Entsprechung
d
keine Entsprechung
fill
entspricht color für Text und background-color für alles andere
stroke
entspricht border, aber kann nicht auf einzelne Seiten eines Elements begrenzt werden.

Auch das SVG-transform-Attribut kann durch die entsprechende CSS-Eigenschaft transform ersetzt werden. Allerdings besser als Kopie speichern, denn die grafischen Editoren erkennen die CSS-Transformationen nicht unbedingt.

Ableitung des Spektralfarbzugs aus dem RGB-Dreieck durch negatives Rot Y X R B G
Ableitung des Spektralfarbzugs aus dem RGB-Dreieck durch negatives Rot Y X R B G

Grafik: Herleitung der CIE-Farbtafel

<g transform="rotate(-15 80 420)">

entspricht

<g style="transform-origin: 80px 420px; transform:rotate(-15deg)">

CSS transform auf SVG-Elemente funktioniert nicht in Internet Explorer und Edge.

SVG style-Attribut

Das style-Attribut SVG-Element funktioniert in jedem SVG-Tag. Wenn Attribute im style-Attribut per CSS überschrieben werden, setzt sich die CSS-Eigenschaft aus dem style-Attribut durch.

<rect style="fill: beige" fill="aliceblue" width="300" height="100" />

Das Element wird mit beige gefüllt, weil sich die Deklarationen im style-Attribut über das fill-Attribut durchsetzen. Genauso wie bei HTML-Elementen sitzt ein style-Attribut näher am Element als class – style setzt sich also auch gegenüber globalen CSS-Deklarationen durch.

style-Tag und Breakpoints für SVG

Ein style-Tag wirkt auf ein oder mehrere SVG-Elemente genauso wie CSS-Regeln des style-Tags im Kopf der HTML-Seite und wirkt auf Elemente mit einem class- oder id-Attribut, aber auch direkt auf einen SVG-Element-Namen als Selektor.

SVG setzt auch CSS Media Queries für Breakpoints um.

.handleLarge { display: none; fill: #EDEE90}
.handleLeft { fill: #EDEE90}
.potbody { fill: #EDEE90} 

@media (min-width: 600px) {
   .handleLarge { display: block;fill: #90B7DA}
   .handleLeft { display: none}
   .potbody { fill: #90B7DA} 
}

Zuverlässig funktionieren nur die Stile in Media Queries für Breakpoints, die im style-Attribut stehen können: z.B fill, font-family, opacity.

Chrome und Safari unterstützen auch transform, stehen damit allerdings alleine da, denn weder IE oder EDGE noch Firefox machen mit.

CSS-Datei in SVG linken oder einbinden

SVG bindet eine externe CSS-Datei durch einen XML-Prolog am Anfang des Markups ein.

<?xml-stylesheet type="text/css" href="svg-style.css" ?>

Das funktioniert nicht, wenn SVG durch ein img-Tag eingebunden wird, denn SVG darf sich keine externe Datei an Land ziehen. Um CSS-Stile aus einer CSS-Datei zu ziehen, muss SVG inline in das HTML der Seite gesetzt werden oder muss mit einem iframe / object eingebettet werden.

SVG-Animationen mit CSS

SVG-Transformationen mit transform und CSS-Transformationen sind sich sehr ähnlich. Statt SVG mit SMIL oder Javascript zu animieren, können also CSS-Transformationen und Animationen mit Keyframes angesetzt werden.

#wing1 {
   animation: swingLeft 3s infinite;
}

#wing2 {
   animation: swingRight 3s infinite;
}

@keyframes swingLeft {
   0% { transform: rotate(0deg); transform-origin: 107px 40px;}
   40% {transform: rotate(30deg); transform-origin: 107px 40px;}
   100% {transform: rotate(0deg); transform-origin: 107px 40px;}
}

@keyframes swingRight {
   0% { transform: rotate(0deg); transform-origin: 140px 40px;}
   40% {transform: rotate(-30deg); transform-origin: 140px 40px;}
   100% {transform: rotate(0deg); transform-origin: 140px 40px;}
}

Internet Explorer und in Microsoft Edge unterstützen SVG Transformationen mit CSS nicht. Da IE und Edge SVG-SMIL-Animationen ebensowenig unterstützen, bleibt nur die SVG-Animation mit Javascript.

SVG mit CSS Keyframe-Animation

Wenn keine Transformationen, sondern Eigenschaften wie Farben und Sichtbarkeit animiert werden, ziehen IE11 und Microsoft Edge gnädig mit.

Der SVG-Spinner passt gut in 1KB und ersetzt die immer noch allgegenwärtigen Warte-Animationen auch als externe Datei.

<svg height="100%" width="100%" viewBox="0 0 500 500">
<style>
@keyframes fade {
   from { fill-opacity: 1; fill:navy; }
   to { fill-opacity: 0}
}
#c1 { animation: fade 3.6s 0s infinite}
#c2 { animation: fade 3.6s -0.3s infinite}
#c3 { animation: fade 3.6s -0.6s infinite}
…
</style>
<g  fill="hsl(30,90%,50%)">
<circle id="c1" cx="250" cy="45" r="30"/>
<circle id="c2" cx="344" cy="69" r="30"/>
<circle id="c3" cx="413" cy="139" r="30"/>
…
</g>
</svg>