SVG/Tutorials/Einstieg/SVG mit CSS stylen

Aus SELFHTML-Wiki
< SVG‎ | Tutorials‎ | Einstieg(Weitergeleitet von XML-Attribut)
Wechseln zu: Navigation, Suche

Informationen zu diesem Text

Lesedauer
30min
Schwierigkeitsgrad
einfach
Vorausgesetztes Wissen
Grundkenntnisse in
• HTML
• CSS

Einer der großen Vorteile von SVG gegenüber zum Beispiel canvas ist die Möglichkeit SVG-Objekte mit CSS zu formatieren.[1]

Anders als bei HTML, wo die Trennung zwischen Inhalt und Design (mittels CSS) schon lange akzeptiert ist, wurde das Aussehen von SVG-Elementen ursprünglich allein durch XML-Attribute festgelegt. Viele davon sind aber Präsentations- oder Geometrie-Attribute, die Sie auch über CSS notieren können. So wird das SVG-Markup schlanker, verständlicher und kann zentral im Stylesheet geändert werden.

XML vs. CSS[Bearbeiten]

XML-Attribute und CSS-inline Style
<circle id="beispiel1"
  cx="50"
  cy="50"
  r="50" 
  fill="#dfac20"
  stroke="#3983ab"
  stroke-width="2" 
/>

<circle id="beispiel2"
  style="cx:50;cy:50;r:50;fill:#dfac20;stroke:#3983ab;stroke-width:2"
/>

Information: Attribute

SVG ist ein XML-Dialekt. SVG-Dokumente bestehen aus einzelnen Elementen. Diese können entweder zwischen Anfangs- und End-Tag weitere Inhalte haben oder wie ein Kreis als inhaltsleere Elemente mit /> enden.

Diese Elemente erhalten durch Attribute bestimmte Eigenschaften. So muss für einen Kreis ein Radius festgelegt werden, zusätzlich kann er zum Beispiel eine Füllung oder eine id erhalten.

Wäre es nicht nützlich, bei größeren Dokumenten immer wiederkehrende Attribute nur einmal zentral festzulegen?
Mit CSS ist dies möglich.


Im ersten Beispiel sind alle Angaben als XML-Attribute deklariert, während im zweiten Beispiel alle Stileigenschaften als Inline-CSS zusammengefasst wurden.[2]

Beachten Sie: Inline-CSS-Code überschreibt zuvor geladene CSS-Formatierungen im head oder von externen Stylesheets.

Noch übersichtlicher ist es, die CSS-Anweisungen in einem style-Element zu notieren:

CSS-Regelsätze innerhalb eines style-Elements
<svg>
  <style type="text/css">
    <![CDATA[
      circle {
        cx: 50;
        cy: 50;
        r:  50;
        fill: #dfac20;
        stroke: #3983ab;
        stroke-width: 2;
      }
    ]]>
  </style> 
  <circle id="beispiel3" />
</svg>

Es ist egal, wo Sie das style-Element notieren:

Beachten Sie: Da in CSS-Angaben anders als in XML-Dokumenten ein > vorkommen darf (z.B. beim Kindkombinator E > F, sollten die Stil-Definitionen in CDATA gekapselt werden.
Beachten Sie: SVG-Grafiken im Wiki
SVG-Grafiken werden durch die MediaWiki-Software nicht direkt gerendert.
Es werden als Fallback für ältere (mittlerweile ausgestorbene) Browser Vorschau-Grafiken im png-Format erstellt. Dieses Skript benötigt die in HTML5 eigentlich nicht mehr notwendige Angabe type="text/css", damit die style-Festlegungen berücksichtigt werden.

SVG und die CSS-Kaskade[Bearbeiten]

Wie oben schon erwähnt, überschreiben inline-CSS-Angaben Einstellungen aus externen Stylesheets oder aus dem style-Bereich. Dies entspricht der Spezifität des style-Attributs in HTML.

Inline-Styles werden aufgrund der höheren Spezifität nur durch !important überschrieben.

Während es ziemlich einfach ist, XML-Attribute durch CSS zu überschreiben, benötigen Sie bei Inline-Styles das Schlüsselwort !important.

Auch wenn es scheint, als ob XML-Attribute nun gar nicht mehr verwendet werden müssen, kann es doch empfehlenswert sein, diese zu setzen, um einen FOUSVG (‘Flash Of Unstyled SVG’) zu vermeiden.[3][4][5]

Möglichkeiten und Grenzen[Bearbeiten]

Eigentlich sollten gerade die Präsentationsattribute, die ja Elemente formatieren und die Darstellung festlegen, in einen externen CSS-Bereich ausgelagert werden, um so durch Klassen eine Vielzahl von Objekten zentral zu formatieren.

Andererseits ist z.B. das path-Element eben doch kein immer gleich aussehendes Objekt, sondern eine Möglichkeit eine Vielzahl von verschiedenen Objekten zu erzeugen. Deshalb wäre es nicht zielführend (und auch nicht möglich) das d-Attribut mit den Pfadangaben ins CSS auszulagern.

Hier gilt es abzuwägen, wie oft ein Attribut wiederverwendet werden soll. Will man einheitliche Linien bei mehreren Elementen, ist eine Festlegung im Stylesheet oder zumindest im oberen style-Abschnitt zu empfehlen.

Festlegungen, die nur einmal getroffen werden, können als XML-Attribut oder innerhalb eines style-Attributs ihren Platz finden.

Präsentationsattribute mit CSS gestalten[Bearbeiten]

Um SVG-Elemente auszuwählen, können Sie fast alle Selektoren sowie dynamische Pseudoklassen :hover, :active und :focus und strukturelle Pseudoklassen wie first- und last-child verwenden und für die Präsentationsattribute CSS-Regeln festlegen.

  • SVG 2
  • Chrome
  • Firefox
  • Edge
  • Opera
  • Safari

Eigentlich kennen Sie die meisten Präsentationsattribute bereits aus HTML und CSS. Andere wie die Geometrie-Attribute werden im Anschluss erklärt.

Farben[Bearbeiten]

Sie haben schon im letzten Kapitel gesehen, dass Objekte in SVG mehr Gestaltungsmöglichkeiten haben:

In der HTML-Welt haben Block-Elemente einen Hintergrund und Rand, Text jedoch nur eine Textfarbe color. In SVG wird jedes Objekt, ob Grundform, Pfad oder Text gerendert, indem es mit fill gefüllt oder mit einer Randlinie versehen wird. Dabei gibt es viel mehr Möglichkeiten zur Gestaltung dieser Eigenschaften.

Grundformen - mit CSS formatiert ansehen …
* {
  stroke: #306f91;
  stroke-width: 1;
}

path {
  fill: #c32e04;	
}

#quadrat {
  fill: #dfac20;	
  stroke-width: 10;
  stroke-opacity: 0.5;
}

Die Grundformen werden über den Universalselektor *ausgewählt und erhalten mit der stroke-Eigenschaft einen blauen Rand, der mit stroke-width eine Breite von 1 erhält. Eine Angabe zur Füllung fehlt, wodurch der Kreis eine schwarze Füllung erhält. Das Dreieck über den Typselektor path ausgewählt und mit fill rot gefüllt (Sollte dort evtl. fill="none" gezeigt werden?)

Das Viereck wird über seine id quadrat angesprochen und gelb gefüllt. Dort wird die Breite der Randlinie auf 10 erhöht. Da die Randlinie mit stroke-opacity durchscheinend ist, sieht man, dass sich die Randlinie sowohl nach innen als auch nach außen ausdehnt. Obwohl das Quadrat ein width="140"-Attribut hat, ist es tatsächlich 150 Pixel breit.

Füllung[Bearbeiten]

Wie Sie eben gesehen haben, werden Formen in SVG ohne weitere Festlegung schwarz gefüllt. Deshalb muss man immer die fill-Eigenschaft festlegen.

Mögliche Werte für fill sind:

  • eine Farbangabe
  • die Angabe none, Hintergrund wird transparent dargestellt
  • die Angabe currentColor, weist den Browser an, einen festgelegten Standardfarbwert zu verwenden
  • eine url(#id) um ein Muster oder Verlauf zu referenzieren

Dies ist besonders wichtig für Pfade und Polygonlinie mit offenen Pfaden:

Füllung ansehen …
Überlegen Sie, wie sich eine Füllung auf die Grafik auswirkt!
Svg-path.jpg
.normal {
  stroke: #3983ab;
  stroke-width: 3;
  fill: none;
  }
.normal:hover,
.normal:focus {
  fill: #dfac20;
  }

Aber auch bei sich mehrfach überschneidenden Figuren kann es zu unerwarteten Effekten kommen:

Füllmethoden ansehen …
Überlegen Sie, wie sich eine Füllung auf die Grafik auswirkt!
Svg-path-2.jpg
.normal {
  stroke: #3983ab;
  stroke-width: 3px;
  fill: #dfac20;
  fill-rule: evenodd;  
  }
#zwei {
  fill-rule: nonzero;
  }
<svg>
      <polygon class="normal" points="100,10 40,198 190,78 10,78 160,198"/>
      <polygon class="normal" id="zwei" points="300,10 240,198 390,78 210,78 360,198"/>
</svg>

Geometrie-Attribute[Bearbeiten]

Mit SVG 2 werden die XML-Attribute für Abmessungen (width, height bzw. r, rx, ry) und Positionsangaben (x, y bzw. cx, cy) zu Präsentationsattributen und können nun ebenfalls mit CSS festgelegt und dadurch z.B. durch hover verändert werden.[6]

  • SVG 2
  • Chrome
  • Firefox
  • Edge
  • Opera
  • Safari
Grundformen - mit CSS formatiert ansehen …
<circle id="kreis" tabindex="1" cx="100" cy="100" />
<path id="dreieck" tabindex="2" d="M200,30 h140 l-70,140 z" />
<rect id="quadrat" tabindex="3" x="380" y="30" width="140" height="140" />
Die Grundformen erhalten neben ihrer id einen tabindex, damit sie auch mit der Tastatur Tab anwählbar sind.
* {
  fill: #dfac20;	
  stroke: #306f91;
  stroke-width: 1;
  transition: all 0.5s ease-out;
}

#kreis {
  r: 50px;
}
#kreis:hover,
#kreis:focus {
  r: 100px;
  fill: #c32e04;
}

#dreieck:hover,
#dreieck:focus {
  fill: #c32e04;	
  stroke-width: 40;
  stroke: #c32e04;	
}

#quadrat:hover,
#quadrat:focus {
  fill: #c32e04;
  width: 150px;
  height: 50px;	
}
Alle Elemente erhalten über den Universalselektor * eine gelbe Füllung, eine schmale blaue Randlinie und eine transition für weiche Übergänge.

Bei :hover und :focus ändern die Grundformen ihre CSS-Eigenschaften:

  • Der Radius des Kreises wird von 50px auf 100px erhöht
    Beachten Sie: Als XML-Attribut benötigt r keine Einheit; innerhalb des style-Elements ist eine Angabe von px erforderlich.
  • Das Dreieck erhält bei :hover mit der Eigenschaft stroke-width einen breiteren Rand. Da der Rand genau auf der Grenze liegt, teilt sich der Rand von 40 so auf, dass er 20px innerhalb und 20px außerhalb des Dreiecks liegt und so Breite und Höhe scheinbar vergrößert.
  • Das Quadrat hat ein width- und ein height-Attribut. Bei :hover werden die Werte durch die entsprechenden CSS-Regelsätze überschrieben.
Beachten Sie: Im IE9-11 werden die Objekte nicht gerendert, da diese noch XML-Attribute benötigen. Verwenden Sie XML-Attribute, um zumindest die Ursprungsdarstellung zu gewährleisten.
Beachten Sie: In Chrome und Opera funktionieren Pseudoklassen wie :hover und :focus beim Aufrufen mit use-Elementen nicht. Verschieben Sie die Kindelemente in das zu animierende Objekt.

Siehe auch:

SVG und Pseudoelemente[Bearbeiten]

Nur der Einsatz von Pseudolementen wie :after und :before ist nicht möglich, da sie in SVG nicht definiert sind. Die Spezifikation ist nicht ganz eindeutig, aber anscheinend werden SVG-Elemente als Grafik wie ein img behandelt, die keine Pseudoelemente erlauben.[7]

Text in SVG[Bearbeiten]

Text in SVG

SVG-Markup ansehen …
<text id="eins" x="10" y="120">
  TEXT 
  <tspan dy=".5em" >in</tspan>
</text>
 
<text id="zwei" x="430 550 650" y="120 170 220">
  SVG
</text>
Der erste Text (id="eins") hat als Inhalt Klartext und ein tspan-Element. Dieses ist mit dem dy-Attribut um 0.5em nach unten verschoben.

Der zweite Text mit der id="zwei" hat mehrere Angaben zu den x- und y-Koordinaten, so dass die einzelnen Zeichen versetzt dargestellt werden.

Des Weiteren sind die text-Elemente mit CSS formatiert:
text {
  font-family:serif;	
  font-size: 120px;
  font-weight: bold;
}
#eins {
  fill: url(#verlauf);
  }
 
#zwei {
  fill: #ffebe6;
  stroke: #c32e04;
  stroke-width: 3px;
  font-family: sans-serif;
  font-size: 160px; 
  font-weight: bold;
}

Wie Sie im Beispiel sehen, kann die fill-Eigenschaft viel mehr als eine Farbangabe verarbeiten:

Verlauf ansehen …
<defs>
  <linearGradient id="verlauf">
    <stop offset="0.095" stop-color="#306f91 "/>
    <stop offset="0.095" stop-color="#dfac20 "/>
    <stop offset=".64" stop-color="#dfac20 "/>
    <stop offset=".67" stop-color="#306f91 "/>
  </linearGradient> 
</defs>

Innerhalb des Definitionsabschnitts wird mit linearGradient ein Verlauf festgelegt, der dann im style-Bereich mit seiner id referenziert wird: fill: url(#verlauf);

Der Verlauf hat mehrere stop-Elemente. Da bei den ersten beiden der offset-Wert gleich ist, kommt es zu einem harten Übergang innerhab des Buchstabens; der dritte und vierte Stop liegen auseinander und sorgen so für einen weichen Übergang.

Hauptartikel: Text-Effekte mit SVG


Weblinks[Bearbeiten]


Quellen[Bearbeiten]

  1. W3C: SVG Styling
  2. tutorials.jenkow: SVG and CSS
  3. css-tricks: Presentation Attributes vs Inline Styles Chris Coyier (23.12.2016)
  4. Sara Soueidan: SVG Style Inheritance and the ‘Flash Of Unstyled SVG’ (01.03.2016)
  5. wikibooks.de: CSS: Kaskadierung, Spezifität und Vererbung: Präsentationsattribute
  6. Dirk Schulze auf Twitter: x, y, width and height are #SVG "presentation attributes" in @webkit now.
  7. stackoverflow: css-before-on-inline-svg