Einstieg in SVG/Einbindung

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
SVG hat gegenüber Rastergrafiken und Canvas viele Vorteile, die sie immer beliebter machen.
  • Text wird als Klartext gerendert und damit von Screenreadern lesbar, bzw. von Suchmaschinen auffindbar
  • SVGs können ohne Qualitätsverlust skaliert werden, weil das Bild nicht Pixel für Pixel gespeichert ist, sondern quasi als Anweisung, wie es gezeichnet wird
  • inline-SVGs können mit CSS gestaltet und animiert werden.
    Dabei können auch Benutzereinstellungen wie prefers-color-scheme und prefers-reduced-motion berücksichtigt werden.

Diese Kapitel zeigt verschiedene Möglichkeiten SVG-Grafiken oder ganze SVG-Codeabschnitte in Webseiten einzubinden. Allerdings gibt es einige Dinge, die du beachten musst, damit deine SVGs barrierefrei sind.[1] [2] [3]

SVG-Dokumente

SVG-Grafiken bestehen aus Text, der geometrische Formen beschreibt. Der Browser liest diese Angaben und stellt daraus das Bild dar. Solche Dateien werden in der Regel als .svg gespeichert. Der MIME-Type ist image/svg+xml. Ursprünglich konnte man SVG-Dokumente nur in Bildbetrachtungsprogrammen wie dem Adobe SVG-Viewer, bzw. Batik-Viewer von Apache ansehen. Heute ist es möglich SVG direkt in allen Browsern ohne Plugins darzustellen. [4]

Grundgerüst eines XML-Dokuments

  • Standalone-SVGs
    • Namensraum angeben
    • Viewport und viewBox

    Erstelle eigene SVG-Dokumente, die du als Bild oder Multimediaobjekt einbinden kannst.


Die Einbindung von .svg- Grafiken ist sehr einfach, entweder direkt über das img-Element, mit picture oder mit Hilfe von object.

SVG in img-Elementen

Der einfachste Weg ist es, ein SVG-Dokument als Bild mit <img>-Element mit einem Alternativtext wie folgt einzubetten:

Referenz auf Bild mit Alternativtext und role-Attribut
<img src="advent.svg"
     alt="Baum mit brennender Kerze"
     role="img"
>

Dies hat viele Vorteile:

+ einfacher und unkomplizierter Aufruf über die URL und den Dateinamen

+ „normale“ Nutzer müssen sich nicht mit den inneren Bestandteilen des SVG-Dokuments beschäftigen

+ CSS-Animationen und SMIL möglich

Allerdings wird das SVG vom Browser als externe Bildressource behandelt, ähnlich wie ein PNG oder JPG – obwohl es technisch gesehen textbasiert ist.

Das hat mehrere wichtige Konsequenzen:

CSS-Angaben der Webseite wirken nicht
   Styles müssen im SVG definiert werden.

eine solche Grafik ist kein Teil des DOM, ein Einsatz von JavaScript ist nicht möglich

Es sind keine Links im SVG möglich

SVG als Multimedia-Objekt mit object

Soll eine SVG-Grafik weiterhin als externe Datei eingebunden werden, dabei aber dennoch interaktiv oder animierbar sein, kann das <object>-Element verwendet werden. Im Gegensatz zum <img>-Element wird das SVG dabei als eigenes Dokument geladen, dessen Inhalte über JavaScript und CSS gezielt angesprochen werden können.

Das <object>-Element stellt damit einen Mittelweg dar: Die Grafik bleibt extern, ist aber nicht vollständig vom Dokument isoliert.


svg-Grafiken einbinden ansehen …
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
</head>

<body>
  <h1>svg-Grafiken einbinden</h1>
 
  <object data="Self-Logo.svg" type="image/svg+xml">
  
    <!---Fallback--->
    Ihr Browser kann leider kein svg darstellen!  
  </object>

    
</body>
</html>


In img- und object-Elementen kannst du SVG-Grafiken ganz einfach mit prozentualen Breitenangaben an die Größe des Elterncontainers anpassen.

responsive Bilder ansehen …
img {
  width: 100%; 
  height: auto;
}
<img src="ubongo.svg" alt="ubongo">

Die Breite passt sich durch den Wert 100% an die Breite des Elternelements an.

Die Höhe wird durch den Wert auto entsprechend angepasst.

+ Animation des Objekts durch JavaScript und Web Animations möglich

+ Formen können im SVG-Quelltext mit Links ergänzt werden (responsive Imagemaps)

object wird in CMS oft nicht unterstützt (Einsatz im CMS)


im iframe

Ähnlich wie die Variante mit object funktioniert eine Einbindung in einem <iframe>:

+ SVG darf Links enthalten.

+ Manipulation des Objekts durch JavaScript möglich.

+ domainübergreifend einsetzbar

nicht 100% responsiv


svg-Grafiken im iframe
 
  <iframe height="200" width="400" src="document.svg" scrolling="no">
  
    <!---Fallback--->
  <img src="document.png" width="400" height="200" alt />
</iframe>

    
</body>
</html>

als Hintergrundbild im CSS

SVG-Dokumente können aber auch als background-image in CSS eingebunden werden.

SVG als externe Hintergrundgrafik ansehen …
p::first-letter{
/* Image-Replacement */ 
  border: 0; 
  font: 0/0 a; 
  text-shadow: none; 
  color: transparent;
}

p span{
  display:inline-block;
  float:left;
  width: 98px;
  height:106px;
  margin-right: 0.3em; 
 
/* Hintergrundbild */
  background-image: url("Initiale_E.svg");
  background-repeat: no-repeat;
  background-size: contain;
}
<p>
  <span>E</span>s war einmal eine kleine süße Dirne, 
  ...
</p>

In diesem Beispiel wurde der Anfangsbuchstabe des Texts durch eine SVG-Grafik ersetzt (Initiale). Das Hintergrundbild wurde mit background-size: contain; passend skaliert.


+ einfache Einbindung mit url('…')

keine CSS-Regeln für :hover möglich

Manipulation durch JavaScript nicht möglich

SVG als Data-URL im CSS

Externe Grafiken benötigen einen zusätzlichen HTTP-Request. Wenn du diesen umgehen willst, kannst du SVG-Grafiken auch direkt in dein HTML oder ins CSS einbauen. Dazu muss man die Grafik zunächst als Data-URL kodieren. Allerdings sind heutige Browser nicht sehr streng beim Interpretieren von Data-URLs, man kann auf die Codierung vieler Zeichen verzichten. Unumgänglich ist aber

  • die Codierung des Zeichens # als %23
  • die Codierung von ' als %27 oder " als %22, je nachdem, welchen Zeichenkettenbegrenzer man für die Data-URL verwendet
  • das Maskieren von Zeilenumbrüchen durch \ - oder die Zeilenumbrüche werden entfernt
  • Das Einschließen der Data-URL in Anführungszeichen, wenn Klammern, Anführungszeichen, Whitespace oder Zeichen mit einem Zeichencode über 127 darin verwendet werden

Ansonten muss lediglich die Zeichenkette data:image/svg+xml;utf-8, vor der SVG-Datei stehen. Das Link-Icon des Wiki ließe sich in der „Spar-Codierung“ wie folgt erzeugen:

Beispiel ansehen …
a {
  display: inline-block;
  text-decoration: none;  
  padding-right: 1em;
  background: 
    url('data:image/svg+xml;utf-8,\
    <svg width="16" height="16" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">\
      <polygon points="2,2 5,2 5,3 3,3 3,9 9,9 9,7 10,7 10,10 2,10"/>\
      <polygon points="6.2,2 10,2 10,5.79 8.58,4.37 6.5,6.5 5.5,5.5 7.6,3.4"/>\
    </svg>') right no-repeat;	
}

Anstelle einer externen Referenz wird das SVG direkt notiert. Dabei müssen der MIME-Type und die Zeichenkodierung angegeben werden.

Beachte, dass alle Zeilenumbrüche im SVG-Code entweder maskiert oder entfernt werden müssen.
Die Daten in Data-URLs müssen laut Standard URL-encodiert sein, viele Browser akzeptieren jedoch auch nicht URL-encodierte SVGs.

+ :hover-Effekte möglich

+ kein HTTP-Request nötig

CSS wird groß und unübersichtlich


  • URL-Encoding
    SVGs als Data-URL codieren


Inline-SVG

Statt eine externe SVG-Datei als Data-URL zu codieren, kannst du auch das <svg>-Element direkt in deiner HTML Datei verwenden. Die Elemente eines solchen SVG werden Teil des DOM. Das heißt:

  1. Du kannst sie durch das Stylesheet deiner HTML-Seite formatieren und
  2. Du kannst auch mit JavaScript darauf zugreifen, um das SVG-Bild zu animieren oder zu transformieren.

+ Animationen und Manipulationen mittels CSS oder JavaScript sind problemlos möglich

+ kein HTTP-Request nötig

+ Verlinkungen innerhalb der SVG sind möglich

HTML-Markup wird groß und unübersichtlich

svg-Grafiken einbinden ansehen …
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Beispiel: Einbindung von Inline-SVG</title>
</head>
 
<body>
  <h1>Beispiel: Einbindung von Inline-SVG</h1>
  <svg>
  <style>
    .gelb{
	fill:	rgb(223 172 32);
	stroke-width:	1;
	stroke:	rgb(40 130 225);
    }
    .blau{
	fill:	rgb(57 131 171);
    }
 
    .linie,.pblau,.quad {
        fill:	none;
	stroke-width:	1;
	stroke-linecap:	round;
	stroke:	rgb(40 130 225);	
    }
 
    .pblau{
	fill:	rgb(40 130 225);
	stroke:white;
    }
    .quad{
	fill:	white;
    }
 
</style>
  <g id="Layer1">
    <path class="gelb"
	      d="M141,195 C164,189 178,173 178,136 C178,87 150,85 111,74 C106,73 86,67 82,64 C81,62 81,60 81,59 C81,46 89,48 100,48 C110,48 120,48 131,49 
	         C138,50 145,51 152,51 C170,51 170,38 170,23 C170,13 168,8 163,5 L183,5 C199,5 195,10 195,169 L195,183 C195,189 189,195 183,195 L141,195 Z"/>
    <path class="blau" 
	      d="M37,195 L16,195 C10,195 5,189 5,183 L5,16 C5,10 10,5 16,5 L61,5 C39,11 24,26 24,62 C24,75 27,91 37,100 C55,117 114,125 119,130 C121,133 
		     120,137 120,140 C120,150 114,150 105,150 C92,150 79,149 66,148 C59,147 51,145 44,145 C30,145 28,156 28,167 L28,174 C28,186 28,192 37,195Z" />
  </g>
 
  <g id="Linien">
    <path d="M111,74 L150,84" class="linie"/>
    <path d="M178,174 L178,87" class="linie"/>
    <path d="M141,195 L165,189" class="linie"/>
  </g>
    <g id="Punkte_blau">
      <path d="M165,185 C167,185 169,186 169,189 C169,191 167,193 165,193 C162,193 161,191 161,189 C161,186 162,185 165,185Z" class="pblau"/>
      <path d="M178,170 C180,170 182,171 182,174 C182,176 180,178 178,178 C176,178 174,176 174,174 C174,171 176,170 178,170Z" class="pblau"/>
      <path d="M178,132 C180,132 182,133 182,136 C182,138 180,140 178,140 C176,140 174,138 174,136 C174,133 176,132 178,132Z" class="pblau"/>
      <path d="M178,83 C180,83 182,84 182,87 C182,89 180,91 178,91 C176,91 174,89 174,87 C174,84 176,83 178,83Z" class="pblau"/>
      <path d="M150,80 C152,80 154,81 154,84 C154,86 152,88 150,88 C147,88 146,86 146,84 C146,81 147,80 150,80Z" class="pblau"/>
    </g>
   <g id="Punkte_weiss">
      <path d="M111,70 C113,70 116,72 116,74 C116,76 113,79 111,79 C109,79 107,76 107,74 C107,72 109,70 111,70Z" class="quad"/>
      <path d="M82,59 C84,59 87,61 87,63 C87,65 84,68 82,68 C80,68 78,65 78,63 C78,61 80,59 82,59Z" class="quad"/>
      <path d="M81,54 C83,54 86,56 86,58 C86,60 83,63 81,63 C79,63 77,60 77,58 C77,56 79,54 81,54Z" class="quad"/>
      <path d="M99 44C101 44 104 46 104 48.5 C104 50 101 53 99 53C97 53 95 50 95 48C95 46 97 44 99 44Z" class="quad"/>
      <path d="M131,45 C133,45 136,47 136,49 C136,51 133,54 131,54 C129,54 127,51 127,49 C127,47 129,45 131,45Z" class="quad"/>
      <path d="M151,47 C153,47 156,49 156,51 C156,53 153,56 151,56 C149,56 147,53 147,51 C147,49 149,47 151,47Z" class="quad"/>
      <path d="M170,19 C172,19 175,21 175,23 C175,25 172,28 170,28 C168,28 166,25 166,23 C166,21 168,19 170,19Z" class="quad"/>
   </g>
   <g id="Quadrate">
      <rect x="137" y="191" width="8" height="8" class="quad"/>
      <rect x="179" y="191" width="8" height="8" class="quad"/>
      <rect x="191" y="179" width="8" height="8" class="quad"/>
      <rect x="191" y="12" width="8" height="8" class="quad"/>
      <rect x="179" y="1" width="8" height="8" class="quad"/>
      <rect x="159" y="1" width="8" height="8" class="quad"/>
    </g>
  </svg>
</body>
</html>

In der vorliegenden Dokumentation beschäftigen wir uns hauptsächlich mit dieser direkten Art der Einbindung von SVG-Grafiken in Webseiten, die viele Vorteile bietet.

Einsatz im CMS

SVG ist nicht nur ein Grafikformat, sondern wie HTML eine Auszeichnungssprache, die auch die Einbindung von Skripten erlaubt. Deshalb ist der Einsatz von SVG in vielen Content Management Systemen, wie auch in unserem Wiki[5] , blockiert. Allerdings gibt es Möglichkeiten, den SVG-Code von potentiell schädlichen Skripten zu „säubern“ und dann einzubinden.

WordPress

WordPress ermöglicht den Upload von Medien und Bildern verschiedener Formate. Dabei wird vor dem Hochladen der MIME-Type überprüft, wobei in der Grundeinstellung SVGs abgelehnt werden. Dies ist nicht unbegründet, da SVG-Dateien JavaScript-Code enthalten können und damit unerwünschte Dinge tun können.

Allerdings kann man mit einigen kleinen Schritten den Upload und die anschließende Verwendung von SVG ermöglichen:

Einerseits kann dazu in die functions.php des Child Themes eine Funktion hinzugefügt werden[6], die dafür sorgt, dass Wordpress den MIME-Type erkennt und damit SVG-Dateien akzeptiert.

Andererseits werden die SVG-Dateien durch diese primitive Lösung nicht auf schädlichen Inhalt wie beispielsweise JavaScript überprüft, weshalb ein Plugin verwendet werden sollte, das den SVG-Upload auf bestimmte Nutzer einschränkt oder SVGs auf eingebettete unerwünschte Eigenschaften wie JavaScript überprüft:

  • SVG Support – Der SVG-Upload lässt sich nur für bestimmte Nutzer freigeben
  • Safe SVG – SVGs werden auf JavaScript und andere unerwünschte Eigenschaften überprüft. Die dafür genutzte Bibliothek kann auch unabhängig vom Plugin benutzt werden[7].

Alternativ kann man SVGs als Hintergrundbilder über CSS einbinden.

Drupal


Weblinks

  1. W3C: Accessibility Features of SVG W3C Note 7 August 2000
    keine große Hilfe; verwendet bei Reusing Text sogar noch das obsolete tref-Element.
    W3C: SVG Accessibility API Mappings W3C Working Draft 10 May 2018
  2. smashingmagazine: Accessible SVGs: Perfect Patterns For Screen Reader Users von Carie Fisher, 26.05.2021
  3. css-tricks: Accessible SVGs Heather Migliorisi vom Jul 6, 2016
  4. Statistiken zeigen oft noch einige Promille von IE8-Nutzern. Dabei ist aber anzunehmen, dass es sich zum überwiegenden Teil um Bots handelt.
  5. Self-Forum: SVG-Grafiken im Wiki nur als png-Vorschau von Matthias Scharwies (18.03.2016)
  6. Kulturbanause.de SVG-Dateien in die WordPress-Mediathek hochladen
  7. SVG-Sanitizer
  • svgwg.org: Beispiele, welche Interaktivität bei den verschiedenen Einbindungen möglich ist.