Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Mehr als Logos und Icons

Scalable Vector Graphics

Mehr als Logos und Icons

Vektorgrafiken werden immer häufiger im Web eingesetzt. Allerdings beschränkt sich das oft noch darauf, Logos oder Icons einzubauen. Dabei verfügen SVG über eine ganze Reihe nützlicher Funktionen, die Webworker noch lange nicht ausgereizt haben. Zum Beispiel bietet uns Text in SVG Möglichkeiten, die uns über reines CSS nicht zur Verfügung stehen.

Dank SVG gibt es einen Webstandard, mit dem wir Logos, Illustrationen und Infografiken als echte Vektorgrafiken im Web abbilden können. Der Vorteil ist natürlich, dass sich die Grafiken verlustfrei skalieren lassen. Als grundlegende Formen stehen uns zur Verfügung:

rect
für ein Rechteck,
circle
für einen Kreis,
ellipse
für eine Ellipse,
line
zieht eine Linie zwischen zwei Punkten,
polyline
zieht eine Linie von Punkt zu Punkt zu Punkt…,
polygon
ist ähnlich zu polyline, nur werden hier der erste und der letzte Punkt miteinander verbunden,
path
für eine beliebige Form.

Text in SVG

Neben diesen Formen ist es auch möglich, über das text-Element reinen Text zu setzen. Um diesen Text zu stylen, habt ihr mehrere Möglichkeiten. Dabei müsst ihr beachten, dass sich die Eigenschaften von den üblichen CSS-Text-Eigenschaften teilweise etwas unterscheiden. Statt color setzt ihr eine Textfarbe etwa über fill.

  1. <svg width="100%" height="30" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg">
  2.   <text class="headline1" x="0" y="30">
  3.     Eine einfache Überschrift
  4.   </text>
  5. </svg>
  1. .headline1 {
  2.   font-size: 30px;
  3.   fill: #000;
  4.   font-family: Calibri, Arial, Verdana, sans-serif;
  5. }
Eine einfache Überschrift
Einfacher Text, innerhalb eines SVG gesetzt. Für die Semantik kann das SVG später in einer hx liegen.

Das SVG lässt sich nun als echte Überschrift beispielsweise in eine h1 packen. Der Text kann ganz normal markiert und kopiert werden.

Das Beispiel oben ist in dieser Form natürlich sinnfrei. Nützlich wird das Konstrukt erst, wenn andere Fähigkeiten von SVG ins Spiel kommen. Zum Beispiel könnt ihr den Text mit einer Outline versehen.

  1. <svg width="100%" height="42" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg">
  2.   <text class="headline2" x="10" y="40">
  3.     Eine einfache Überschrift
  4.   </text>
  5. </svg>
  1. .headline2 {
  2.   font-size: 40px;
  3.   fill: none;
  4.   stroke: #000000;
  5.   font-family: Calibri, Arial, Verdana, sans-serif;
  6. }
Eine einfache Überschrift
SVG bieten die einfachste Möglichkeit, die Outline eines Textes abzubilden.

text-stroke: In den offiziellen Spezifikationen des W3C gibt es keine Möglichkeit, solch eine Outline zu erzeugen. Allerdings haben die Webkit-Browser hier vorgelegt und mit der Eigenschaft text-stroke solch eine Möglichkeit geschaffen. Das unterstützen laut Can I use auch einige Browser, allerdings weder IE noch Firefox.

Die Variante über das SVG funktioniert hingegen in allen modernen Browser runter bis zum IE9. Der IE8 kann zwar kein SVG, ignoriert diese Tags aber einfach und stellt zumindest den Text dar. Das führt in diesem Beispiel (zufällig) zu willkommener Graceful Degradation.

Neben der durchgezogenen Linie bieten SVG weitere Optionen für die Outline. Mit stroke-dasharray legt ihr etwa Muster fest. Die Eigenschaft erwartet immer paarweise zwei Werte, die für gesetzte Pixel und Lücken stehen. Ein stroke-dasharray: 20 4 10 4 sorgt etwa für 20 Pixel Linie, 4 Pixel Lücke, 10 Pixel Linie, 4 Pixel Lücke.

  1. <svg width="100%" height="42" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg">         
  2.   <text class="headline3" x="10" y="40">
  3.     Eine einfache Überschrift
  4.   </text>
  5. </svg>
  1. .headline3 {
  2.   font-size: 40px;
  3.   fill: none;
  4.   stroke: #000000;
  5.   font-family: Calibri, Arial, Verdana, sans-serif;
  6.   stroke-dasharray: 20 4 10 4;
  7. }
Eine einfache Überschrift
Durch das stroke-dasharray könnt ihr die Outline mit einem Muster ausstatten.

Das funktioniert ebenfalls in allen modernen Browsern, allerdings nervt die Darstellung im Opera etwas. Solange sich die Outline eines Buchstabens mit einer einzigen Linie darstellen lässt, ist alles in Ordnung (etwa bei einem W). Sobald aber zwei getrennte Linien gezogen werden müssen (z.B. bei einem o) verbindet Opera diese beiden Linien, was zu einem falsch gesetzten Strich führt.

Opera verbindet mehrere Linien in einem Buchstaben
Ein etwas größeres Beispiel (kein SVG, sondern ein Screenshot): Opera zieht die Umrisse bei Buchstaben wie a, e, i oder o nicht wie erwartet

Gehen wir einen Schritt weiter und versuchen es mit einer CSS-Animation. Zum Beispiel können wir das stroke-dasharray per @keyframes von 0 500 auf 500 0 verändern. Als Ergebnis werden die Buchstaben des Textes gleichzeitig gemalt. Am Ende bleibt der Text einen Moment stehen (weil die 500 etwas über die benötigte Länge hinaus gehen). Die Animation funktioniert direkt allerdings nur im Firefox. Mit Browser-Prefixes auch in Chrome. Im IE, Safari und Opera sehen Besucher die durchgezogene Linie ohne Animation.

  1. <svg width="100%" height="42" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg"> 
  2.   <text class="headline4" x="10" y="40">
  3.     Eine einfache Überschrift
  4.   </text>
  5. </svg>
  1. /* Für Animationen in Chrome benötigt ihr
  2. noch das -webkit-Prefix
  3. Siehe http://caniuse.com/#feat=css-animation */
  4.  
  5. .headline4 {
  6.   font-size: 40px;
  7.   fill: none;
  8.   stroke: #000000;
  9.   font-family: Calibri, Arial, Verdana, sans-serif;
  10.   animation: moveit 10s infinite;
  11. }
  12. @keyframes moveit {
  13.   0% { stroke-dasharray: 0 500; }
  14.   100% { stroke-dasharray: 500 0; }
  15. }
Eine einfache Überschrift
Bei diesem Text wird die Outline der Buchstaben langsam gezogen. Allerdings nur in Chrome und Firefox.

Typografische Feinheiten: Hier kann es zu Sonderfällen kommen, die von der genutzten Schrift und dem Browser abhängen. Unter Windows wird die Schrift Calibri verwendet. Firefox setzt hierbei das »ft« als Ligatur, also als ein einzelnes Zeichen. Andere Browser zeichnen das f und das t jedoch getrennt.

Neben stroke-dasharray gibt es auch stroke-dashoffset, das festlegt, an welcher Stelle mit dem dasharray begonnen werden soll. So könnten wir etwa mit der Lücke anfangen. Wenn die beiden Werte aufeinander abgestimmt werden, lässt sich auch der stroke-dashoffset animieren, so dass sich die Linien der Outline gleichmäßig bewegen. Auch hier ist die Animation auf Firefox und (mit Prefix) Chrome beschränkt. Die anderen Browser zeigen die statische Outline.

  1. <svg width="100%" height="90" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg"> 
  2.   <rect height="90" width="100%" y="0" x="0" fill="#EEE"/>
  3.   <text class="headline5" x="10" y="80">
  4.     Weihnachtsaktion
  5.   </text>
  6. </svg>
  1. /* Für Animationen in Chrome benötigt ihr
  2. auch hier das -webkit-Prefix */
  3.  
  4. .headline5 {
  5.   font-size: 80px;
  6.   fill: none;
  7.   stroke: #F00;
  8.   stroke-width: 3px;
  9.   font-family: Calibri, Arial, Verdana, sans-serif;
  10.   stroke-dasharray: 9 3;
  11.   animation: moveit2 1s infinite linear;
  12. }
  13. @keyframes moveit2 {
  14.   0% { stroke-dashoffset: 12; }
  15.   100% { stroke-dashoffset: 0; }
  16. }
Weihnachtsaktion
Hier bewegt sich das Muster entlang der Outline. Allerdings ebenfalls nur in Chrome und Firefox.

In Kombination mit einem textPath folgt Text einem beliebigen Pfad. Das wiederum funktioniert in allen modernen Browsern.

  1. <svg width="100%" height="100" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg">        
  2.   <defs>
  3.     <path id="textPath" d="M75,20 a1,1 0 0,0 130,0" />
  4.   </defs>
  5.   <text class="headline6" x="0" y="0">
  6.     <textPath xlink:href="#textPath">
  7.       Immer nur lächeln
  8.     </textPath>
  9.   </text>
  10. </svg>
  1. .headline6 {
  2.   font-size: 28px;
  3.   fill: #000;
  4.   font-family: Calibri, Arial, Verdana, sans-serif;
  5. }
Immer nur lächeln
Mit Hilfe von SVG könnt ihr Texte recht einfach an anderen Pfaden ausrichten. Hier gilt es nur, besonders auf den Lauf der Schrift zu achten. Im Firefox (Windows) passt die Calibri wunderbar. In anderen Browsern werden bei anderen Schriften aber ggf. ein paar Buchstaben verschluckt.

Barrierefreiheit: SVG können unterschiedlich komplex sein. Insofern sind sie auch nicht generell barrierefrei oder nicht. Einige Aspekte funktionieren recht gut, bei anderen können wir mit WAI-ARIA etwas nachhelfen. Siehe etwa »Tips for Creating Accessible SVG«. Das text-Element innerhalb von SVG wird Screenreadern als reiner Text übermittelt. Dabei spielt es keine Rolle, ob wir die Outline hervorheben, Animationen nutzen oder den Text an einem Pfad ausrichten.

Links in SVG

Neben Text ist es auch erlaubt, übliche Links in SVG-Dateien einzusetzen. Allerdings müsst ihr das Attribut href hier durch xlink:href ersetzen. Das Schöne daran: Die Links verhalten sich wie gewöhnliche Links außerhalb eines SVG. Sie können also mit Pseudoklassen wie :hover, :focus und :target angesprochen werden und bekommen auch den Fokus, wenn ein Nutzer durch die Website tabbt.

  1. <svg width="100%" height="20" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg"> 
  2.   <text x="0" y="15">
  3.     <a xlink:href="#ademo1" class="ademo" id="ademo1">Link 1</a>,
  4.     <a xlink:href="#ademo2" class="ademo" id="ademo2">Link 2</a> und
  5.     <a xlink:href="#ademo3" class="ademo" id="ademo3">Link 3</a>.
  6.   </text>
  7. </svg>
  1. .ademo {
  2.   fill: #000;
  3.   text-decoration: underline;
  4. }
  5. .ademo:hover {
  6.   text-decoration: none;
  7.   fill: #F00;
  8. }
  9. .ademo:focus {
  10.   text-decoration: none;
  11.   fill: #0F0;
  12. }
  13. .ademo:target {
  14.   text-decoration: none;
  15.   fill: #00F;
  16. }
Link 1, Link 2 und Link 3.
Die drei Links in diesem Text ändern ihre Textfarbe bei :hover (rot), :focus (grün) und :target (blau). Die Links befinden sich zwar innerhalb eines SVG, sind aber trotzdem ganz normal verwendbar.

Das lässt sich ideal in Infografiken verwenden. Mit richtig genutzten Links ist die Infografik für Tastaturnutzer besser bedienbar. Und durch den Einsatz von :target ist es möglich, Deep Links auf bestimmte Informationen innerhalb der Infografik zu setzen. Ein nettes Extra: In der Deutschlandkarte sind die Länder als Pfade innerhalb eines Links eingebunden. Die Linkfläche orientiert sich nun am tatsächlichen Pfad, nicht etwa an einem Rechteck um den Pfad herum.

Baden-Württemberg Einwohner: 10.631.278 Bayern Einwohner: 12.604.244 Berlin Einwohner: 3.421.829 Brandenburg Einwohner: 2.449.193 Bremen Einwohner: 657.391 Hamburg Einwohner: 1.746.342 Hessen Einwohner: 6.045.425 Mecklenburg-Vorpommern Einwohner: 1.596.505 Niedersachsen Einwohner: 7.790.559 Nordrhein-Westfalen Einwohner: 17.571.856 Rheinland-Pfalz Einwohner: 3.994.366 Saarland Einwohner: 990.718 Sachsen Einwohner: 4.046.385 Sachsen-Anhalt Einwohner: 2.244.577 Schleswig-Holstein Einwohner: 2.815.955 Thüringen Einwohner: 2.160.840
In dieser Deutschladkarte sind die Länder als Links angelegt und mit :hover, :focus und :target ausgestattet. Das klappt in allen modernen Browsern.

Bei der Infografik sind einige Dinge zu beachten:

Innerhalb eines SVG können Elemente nicht mit z-index nach vorne geholt werden. Es gilt die Reihenfolge, in der die Elemente in dem SVG stehen. Deshalb müssen erst die 16 Länder gezeichnet werden, danach folgen die 16 Infokästen. Um :target zu nutzen, steckt der Umriss des Landes bereits in einem Link mit der id des Landes (#berlin). Die Infos zu einem Land sind in einem g-Element gruppiert, das die Klasse des Landes trägt (.berlin). Dann können wir die Klasse über den general sibling combinator ~ ansprechen.

  1. #berlin:hover ~ g.berlin,
  2. #berlin:focus ~ g.berlin,
  3. #berlin:target ~ g.berlin
  4. {
  5.   opacity: 1;
  6.   transition: all 0.3s linear;
  7. }

Bewegt ein Nutzer die Maus über einen Land, erscheint der Infokasten. Bewegt er die Maus nun über den Kasten, verliert das Land den :hover-Status und der Infokasten verschwindet. Das führt zu einem lästigen Flackern des Infokastens. Abhilfe schafft der Tipp von Sascha Postner zu Pointer-Events.

  1. .landinfo
  2. {
  3.   pointer-events: none;
  4. }

Bei solchen interaktiven SVG kommt es darauf an, wie diese jeweils ins HTML-Dokument eingebunden sind. Über das img-Element wird das SVG zwar angezeigt, ist aber nicht interaktiv. Als object-Element oder in einem iframe funktionieren die Zustände der Pseudoklassen, doch die URL ändert sich nicht, was aber sinnvoll sein kann, wenn ihr Nutzern den Deep Link zugänglich machen möchtet. Für dieses Beispiel ist es also am besten, das SVG direkt in die HTML-Datei zu schreiben.

  1. <object type="image/svg+xml" data="bundeslaender.svg">
  2.   <!-- Fallback Text oder Bild -->
  3.   Beispiel für ein SVG
  4. </object>
Beispiel für ein SVG
Dasselbe SVG, dieses Mal aber per object-Element eingebunden. :hover und :focus klappen nach wie vor. Das :target funktioniert an sich auch, ändert aber nicht mehr die URL.

HTML in SVG

Die SVG-Beispiele oben mit reinem Text lassen sich noch in andere HTML-Elemente einsetzen, damit der Text eine semantische Bedeutung bekommt. Was aber, wenn das SVG mehrere Texte enthält, die semantisch unterschiedlich ausgezeichnet werden müssten? Zum Beispiel für erklärende Texte innerhalb einer Infografik? Für diesen Fall gibt es das foreignObject-Element, das HTML innerhalb eines SVG erlaubt.

  1. <svg width="100%" height="200" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg">
  2.   <foreignObject width="100%" height="200">
  3.     <h1>Überschrift 1. Ordnung</h1>
  4.     <p>Ein Beispieltext mit einer <em>Betonung</em>.</p>
  5.     <h1>Überschrift 1. Ordnung</h1>
  6.     <p>Ein Beispieltext mit einer <strong>starken Betonung</strong>.</p>
  7.   </foreignObject>             
  8. </svg>

Überschrift 1. Ordnung

Ein Beispieltext mit einer Betonung.

Überschrift 2. Ordnung

Ein Beispieltext mit einer starken Betonung.

HTML, eingebettet in SVG. Die Elemente übernehmen das Design, das generell für diese Elemente auf der Website gilt.

Das klappt in allen modernen Browsern, allerdings nicht im Internet Explorer. Hier habt ihr zwei Möglichkeiten. Zum einen könnt ihr das switch-Element benutzen, um verschiedene Inhalte auszugeben. Zum anderen besteht natürlich auch hier die Möglichkeit, Conditional Comments einsetzen, wenn es nur darum geht, dem IE andere Inhalte zu liefern.

Kleine Korrektur nach dem Kommentar von Florence: Für die IE9+ könnt ihr das switch-Element einsetzen, um verschiedene Inhalte auszugeben. Statt des Attributs requiredExtensions müsst ihr allerdings das Attribut requiredFeatures nutzen. Für den IE8 wird auch hier ein Conditional Comment die beste Lösung sein.

  1. <switch>
  2.   <foreignObject width="100" height="50"
  3.  requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
  4.     <!-- Das gewünschte HTML -->
  5.   </foreignObject>
  6.  
  7.   <!-- Alternativer SVG-Inhalt,
  8.  falls foreignObject nicht unterstützt wird -->
  9. </switch>

Responsive Webdesign: Alle gezeigten SVG-Techniken funktionieren auch in Safari unter iOS sowie in Chrome unter Android; dabei laufen die Animationen etwas langsamer ab. Allerdings ist bei den Beispielen auf dieser Seite noch kein responsives Verhalten berücksichtigt. Natürlich wäre es am einfachsten, alle SVG kleiner zu skalieren. Allerdings sieht die Outline in zu kleinen Größen nicht mehr ordentlich aus, und die kleinen Länder lassen sich in der Karte nicht mehr gut auf dem Touchscreen treffen. Sinnvoller kann es also sein, stattdessen reinen Text oder eine Tabelle der Einwohnerzahlen anzubieten.

SVG bieten noch viele anderen Eigenschaften, die sich an der einen oder anderen Stelle lohnen können. Zum Beispiel Animationen mit SMIL oder via snap.svg, Muster, Gradienten, Masken und Filter. Die Optionen sind zahlreich und sicher auch nicht ausgereizt. Leider nützen euch bei den Details die allgemeinen Infos auf Can I use nicht mehr viel, und es gilt, die benötigten Funktionen selbst in den Browsern zu testen. Zum Einarbeiten in SVG gibt es ein paar gute Anlaufstellen:

Kommentare

Marty
am 22.12.2014 - 11:07

Das ist ja wirklich erstaunlich was mit SVG alles möglich ist mittlerweile.

Frage(n):
1. Kann man eine Überschrift zentrieren? Wenn ja wie?

2. Kann man bei einer Überschrift jeden Buchstaben in einer anderen Farbe färben? Wie?

Danke und super Artikel!
+1

Permanenter Link
Nicolai Schwarz

Nicolai Schwarz (Autor)
am 22.12.2014 - 12:38

1. Kann man eine Überschrift zentrieren? Wenn ja wie?

Ja, das geht über text-anchor. Zum Beispiel:

  1. <svg width="100%" height="30" xmlns="http://www.w3.org/2000/svg" version="1.2" xmlns:svg="http://www.w3.org/2000/svg">
  2.   <text x="50%" y="30px">Mein Text</text>
  3. </svg>
  1. text { font-size: 30px; text-anchor: middle; }

Ergibt:

Mein Text

2. Kann man bei einer Überschrift jeden Buchstaben in einer anderen Farbe färben? Wie?

Auch das geht. Innerhalb eines text-Elements kannst du weitere tspan-Elemente für die Buchstaben nutzen. Mit unterschiedlichen Klassen färbst du die Buchstaben ein. Innerhalb eines foreignObject-Elements klappt das ebenso mit einfachen span-Elemente für die Buchstaben.

Permanenter Link

Florence Maurice
am 22.12.2014 - 15:03

schöne Beispiele und Ausführungen!

.... kleiner Hinweis: der Link bei "das switch-Element benutzen, um verschiedene Inhalte auszugeben" geht nicht, weil aus dem href- ein hef-Attribut geworden ist ...

Permanenter Link
Jens Grochtdreis

Jens Grochtdreis (Webkraut)
am 22.12.2014 - 15:25

Danke für den Hinweis, Florence, ich habe es korrigiert.

Permanenter Link

Florence Maurice
am 22.12.2014 - 15:08

... und noch ne Ergänzung wegen dem fehlenden Support für foreignObject im IE: Conditional Comments funktionieren nicht mehr im IE10 und größer, sind hier also keine Möglichkeit.

Permanenter Link
Nicolai Schwarz

Nicolai Schwarz (Autor)
am 23.12.2014 - 01:24

Danke, stimmt. Macht aber nix. Aber IE9 klappt die Lösung per switch und alternativem Inhalt. Darunter könnte man auf Conditional Comments setzen. Ich habe den Artikel korrigiert.

Permanenter Link

Florence Maurice
am 23.12.2014 - 01:30

danke für die Detailklärung. Das mit switch scheint echt interessant, muss mir das mal genauer ansehen ...

Permanenter Link

Thomas Meinike
am 22.12.2014 - 15:49

Eine weitere u. a. für Text interessante Technik ist das für SVG 2 vorgesehene Attribut paint-order="stroke", aktuell mindestens von Firefox und Opera unterstützt (siehe Material zu einem kürzlich gehaltenen Vortrag).

Permanenter Link

Philip
am 03.01.2015 - 16:46

Cooler Artikel! Was ich bisher noch nicht geschafft habe ist die Manipulation von SVG Icons via Pseudo-Klasse (:hover) in einem SVG-Sprite, das über ein CSS Pseudo-Element eingebunden wird. Kennt da jemand von euch zufälliger Weise eine Möglichkeit? Bisher klappt es nur, wenn ich das SVG-Sprite direkt ins HTML-Markup einbinde, aber das finde ich doof.

Viele Grüße

Philip

Permanenter Link

Die Kommentare sind geschlossen.