SVG/Tutorials/Einstieg/SVG in responsiven Webseiten

Aus SELFHTML-Wiki
< SVG‎ | Tutorials‎ | Einstieg(Weitergeleitet von Dimensionslose Größe)
Wechseln zu: Navigation, Suche

Eines der Hauptmerkmale responsiver Webseiten ist die flexible Anpassung von Bildgrößen an die Abmessungen des Viewports. Gerade hier haben skalierbare Vektorgrafiken den Vorteil, immer gestochen scharfe Grafiken darzustellen.

SVG als Leinwand

Ein SVG wird auf eine Leinwand (engl. canvas – nicht zu verwechseln mit dem gleichnamigen Element) gezeichnet. Dies ist eine eigentlich unendlich große (und verlängerbare) Fläche, die aber in einem Viewport mit festen Maßen angezeigt wird. Teile des canvas außerhalb des Viewports werden abgeschnitten und sind nicht sichtbar.

Viewport

"Fenster eines Flugzeugs
Fenster im Flugzeug - man sieht nur einen Ausschnitt

Der Viewport ist die sichtbare Bildfläche. Man kann ihn mit einem Blick aus einem Fenster vergleichen, in dem die Aussicht vollständig oder nur teilweise zu sehen ist.

Der SVG Viewport ist mit dem Viewport der Ansicht einer Webseite vergleichbar. Eine Webseite kann breiter als der Viewport sein und ist oft meist länger. So sind oft nur Teile einer Webseite im aktuellen Viewport sichtbar.

Die Größe des Viewports wird mit den width- und height-Attributen des äußersten svg-Elements festgelegt.

Aufgabe: Öffnen Sie das Beispiel in einem neuen Tab und verändern Sie die Größe des Fensters.
Das SVG skaliert nicht.
SVG mit festen Größen, nicht skalierbar ansehen …
<svg width="600" height=450">
  <!-- SVG-Objekte, die auf die SVG-Leinwand gezeichnet werden-->
</svg>

In SVG können Sie Werte mit oder ohne Maßeinheiten angeben. Eine dimensionslose Größe (engl. unitless value) gilt als Benutzereinheit, der Wert wird aber als entsprechende Anzahl „px“ angenommen. Dies ist sinnvoll, weil so fehleranfällige Umrechnungen von Einheiten vermieden werden. Es sind aber alle Maßeinheiten von Längenangaben möglich.

Dies bedeutet, dass das obere Beispiel einen Viewport von 600px x 450px rendert.

Nachdem Breite und Höhe des (äußersten) svg-Elements gesetzt sind, erstellt der Browser nun …

  • ein Viewport-Koordinatensystem, das seinen Platz im verfügbaren Viewport der Webseite einnimmt, und seinen Ursprung in der linken, oberen Ecke (0,0) hat. Die positive y-Achse geht wie im Box-Modell nach unten und eine dimensionslose Einheit entspricht einem „Pixel“.
  • ein Benutzer-Koordinatensystem, das die Leinwand für die SVG-Grafik umfasst. Anfänglich sind beide Koordinatensysteme gleich.

viewBox

Oft ist es nötig eine vorhandene Grafik so zu skalieren, dass sie in ein bestimmtes Elternelement passt. Mit dem viewBox-Attribut können Sie ein neues Rechteck mit fester Pixelbreite bestimmen, das innerhalb des verfügbaren Viewports des Elternelements beliebig skaliert, verschoben und auch beschnitten werden kann.[1]

Teleskop
Mit einem Teleskop können Sie das Bild skalieren und zoomen.

Syntax

<svg viewBox="0 0 650 450">

Folgende Angaben sind nötig:

  • min-x: x-Koordinate des neuen Koordinatensystems (obere linke Ecke)
  • min-y: y-Koordinate des neuen Koordinatensystems (obere linke Ecke)
  • width: Breite
  • height: Höhe (Negative Angaben oder ein Wert 0 bei der Breite oder Höhe verhindern ein Rendern des svg-Elements.)

Die Angaben können durch Komma oder Leerzeichen getrennt werden.

Das viewBox-Attribut erstellt ein neues Rechteck mit einem neuen Koordinatensystem.

Sie haben nun zwei Koordinatensysteme in der SVG-Grafik:

  • das "eigentliche" Viewport-Koordinatensystem des svg-Elements mit den Attributen width und height
  • das "neue" Benutzer-Koordinatensystem, bestimmt durch das mit dem viewBox-Attribut definierte Rechteck.
Beachten Sie: Sie müssen für die weitere Gestaltung der SVG-Grafik dieses neue Koordinatensystem verwenden!

Mittels einer automatic transformation rechnet der Browser beim Rendern das "neue" Koordinatensystem automatisch auf die im svg-Element wirklich benötigten Werte um.

Aufgabe: Öffnen Sie das Beispiel in einem neuen Tab und verändern Sie die Größes des Fensters.
Das SVG skaliert fließend.
responsives SVG mit viewBox-Attribut ansehen …
svg { 
  width: 100%;
  height: auto;
  }
<svg viewBox="0 0 650 450">
    <defs>
      <pattern id="grid" patternUnits="userSpaceOnUse" width="10" height="10" x="0" y="0">
        <desc>Raster</desc>
        <path d="M0,0 v10 h10" />
      </pattern>
    </defs>

    <rect x="0" y="0" width="650" height="450" fill="url(#grid)"></rect>
    <path fill="#5a9900" d="M20,20 h300 v100 h-100 v100 h-200 z" />
    <path fill="#c32e04" d="M320,20 h200 v200 h-200 z" />
    <path fill="#dfac20" d="M220,120 h100 v100 h100 v100 h-100 v100 h-100 z" />
    <path fill="#3983ab" d="M420,220 h200 v100 h-100 v100 h-200 v-100 h100 z" />
</svg>
Durch die relativen Werte im CSS wird die Grafik entsprechend der verfügbaren Breite passend skaliert. Das width-Attribut erhält hier einen Wert von 100%, damit sich die SVG-Grafik passend in den verfügbaren Platz einfügt.
Die viewBox erstellt ein Rechteck, das bei "0,0" beginnt und eine Breite von 650 sowie eine Höhe von 450 hat. Dieses wird in das eigentliche Koordinatenystem, dessen Werte vom Browser berechnet werden, transformiert.
Beachten Sie: Im XML-Kontext wird das Attribut in CamelCase geschrieben, HTML5 ist case-insensitiv.

Folgende Elemente können das viewBox-Attribut verwenden:

Interaktive viewBox-Demo
(von Sara Soueidan)

Anwendungsbeispiele

Erinnern Sie sich an diese Beispiele aus den vorhergehenden Kapiteln?

Flagge Frankreich ansehen …
<svg width="300" height="200" viewBox="0 0 3 2">
  <desc>Flagge Frankreichs</desc>
  <rect x="0" y="0" width="1" height="2" fill="#0055A4" />
  <rect x="1" y="0" width="1" height="2" fill="white" />
  <rect x="2" y="0" width="1" height="2" fill="#EF4531" />  
</svg>

viewBox="0 0 3 2" bedeutet, dass …

  • ein Bereich mit einem Benutzer-Koordinatensystem von 0,0 bis 3,2 spezifiert wird.
  • die SVG-Grafik auf diesen Bereich zugeschnitten wird
  • der Bereich (in einem Zoom-in-Effekt) in den Viewport skaliert wird
  • 1 Benutzereinheit 100px des Viewport-Koordinatensystems entsprechen


SVG-Uhr: Viewbox mit verschobenem Ursprung ansehen …
<svg viewBox="-100 -100 200 200">
  <circle id="clockface" r="98" />
  <circle id="origin"    r="2" />
</svg>

viewBox="-100 -100 200 200" bedeutet, dass …

  • ein Bereich mit einem Benutzer-Koordinatensystem von -100,-100 bis 100,100 spezifiert wird
    (Der Ursprung 0,0 liegt in der Mitte)
  • die SVG-Grafik auf diesen Bereich zugeschnitten wird
  • der Bereich (in einem Zoom-in-Effekt) in den Viewport von (im CSS festgelegten) 250px x 250px skaliert wird
  • 1 Benutzereinheit 1.25px des Viewport-Koordinatensystems entsprechen

viewBox-Animation

Mit einer dynamischen Änderung des viewBox-Attributs sind Effekte wie Pan & Zoom (engl. für Schwenken und Zoomen) wie Kamerafahrten über eine Landkarte möglich, in der Sie aus einem Startpunkt mit großer Auflösung herauszoomen, über die Karte schweben und am Ziel wieder hereinzoomen.

Da das viewBox-Attribut kein Präsentationsattribut ist, muss die Animation entweder mit SMIL oder mit JavaScript erfolgen.

Achtung!

Nutzer des Firefox können SMIL im Frickl nicht ausprobieren, da die animate-Elemente nicht gerendert werden.
Öffnen Sie das Beispiel mit einem Klick auf Vorschau in einem neuen Tab!
Zoom & Pan ansehen …
<svg viewBox="0 0 800 400">
   ...
  <animate 
    attributeName="viewBox" 
    begin="1s" 
    dur="10s" 
    values="   0    0  800 400; 
             130  130  330 230;
      	       0    0  800 400; 
            -300 -300 1300 500; 
               0    0  800 400" 
   fill="freeze"/>
</svg>

In diesem Beispiel wurde die viewBox mit SMIL animiert, indem in das zu animierende svg-Element ein animate-Element eingefügt wurde. Über das attributeName-Attribut wird die zu animierende Eigenschaft, über values die Werte(paare) notiert. Mit begin="1s" wird der Start um 1s verzögert, die Animation hat eine Dauer von 10s.

Siehe auch:

preserveAspectRatio

Mit dem preserveAspectRatio-Attribut kann das gewünschte Seitenverhältnis festgelegt werden. Bei allen Elementen außer bei image wird preserveAspectRatio ohne ein zuvor gesetztes viewBox-Attribut ignoriert.


Skaliert oder mit „richtigen“ Proportionen? ansehen …
<svg width="100%" height="100%">
	<defs>
		...
	</defs>		
		<rect x="0" y="0" width="100%" height="100%" fill="url(#grid)"></rect>
		
		<svg id="interactive" viewBox="0 0 100 100"  width="50%" height="50%" preserveAspectRatio="meet">
			<rect x="0" y="0" width="100" height="100" fill="url(#linear-gradient)" />
			<path d="M0,0  l100,100 m-100,0 l100,-100" /> </g>
    </svg>
</svg>

Im SVG befindet sich ein weiteres SVG mit einer Grafik. Über preserveAspectRatio kann festgelegt werdne, ob diese in „richtigen“ Proportionen dargestellt wird oder über die gesamte Fläche skaliert wird.

Insbesondere falls Sie bereits mit CSS-Hintergrundbildern gearbeitet haben, können Sie sich die Funktion dieses Attributs anhand der Eigenschaften background-position und background-size vorstellen:

preserveAspectRatio-Schlüsselwort vergleichbar mit Hintergrundbild-Eigenschaft
none background-size: 100% 100%;
xMinYMin background-position: top left;
xMidYMin background-position: top;
xMaxYMin background-position: top right;
xMinYMid background-position: left;
xMidYMid background-position: center;
xMaxYMid background-position: right;
xMinYMax background-position: bottom left;
xMidYMax background-position: bottom;
xMaxYMax background-position: bottom right;
meet background-size: contain;
slice background-size: cover;
Beispiel
<svg viewBox="0 0 650 450" preserveAspectRatio="xMinYMin meet">
    <defs>
      <pattern id="grid" patternUnits="userSpaceOnUse" width="10" height="10" x="0" y="0">
        <desc>Raster</desc>
        <path d="M0,0 v10 h10" />
      </pattern>
    </defs>

    <rect x="0" y="0" width="650" height="450" fill="url(#grid)"></rect>
    <path fill="#5a9900" d="M20,20 h300 v100 h-100 v100 h-200 z" />
    <path fill="#c32e04" d="M320,20 h200 v200 h-200 z" />
    <path fill="#dfac20" d="M220,120 h100 v100 h100 v100 h-100 v100 h-100 z" />
    <path fill="#3983ab" d="M420,220 h200 v100 h-100 v100 h-200 v-100 h100 z" />
</svg>

Das rect-Element wird durch das grid-Pattern gefüllt. Damit das Seitenverhältnis erhalten bleibt und sich die Grafik nicht verzieht, wird erst eine viewBox festgelegt und dannpreserveAspectRatio="xMinYMin meet".


Weblinks

deutsch

Quellen

  1. W3C: ViewBoxAttribute