SVG/Tutorials/Einstieg/SVG in responsiven Webseiten

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

Informationen zu diesem Text

Lesedauer
30min
Schwierigkeitsgrad
mittel
Vorausgesetztes Wissen
Kenntnisse in
• HTML
• CSS
• SVG

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[Bearbeiten]

Ein SVG wird auf eine Leinwand (engl. canvas - nicht zu verwechseln mit dem gleichnamigen Element) gezeichnet. Dies ist ein 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[Bearbeiten]

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.

SVG mit festen Größen ansehen …im Viewport-Emulator
<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[Bearbeiten]

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]

  • SVG 1.1
  • Chrome
  • Firefox
  • IE 9
  • Opera
  • Safari

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.


responsives SVG mit viewBox-Attribut ansehen …im Viewport-Emulator
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.

Information

Man kann die viewBox mit Google Maps vergleichen:
  • Man kann in einen bestimmten Bereich hineinzoomen; dieser wird vergrößert innerhalb des Viewports dargestellt.
  • Die restliche Karte ist noch vorhanden, aber nicht sichtbar, weil sie sich außerhalb des Viewports befindet.
Beachten Sie: Im XML-Kontext wird das Attribut in CamelCase geschrieben, HTML5 ist case-insensitiv.
Beachten Sie: Ältere Versionen des Internet Explorers (IE9-11) füllen nicht die gewünschte Breite, sondern rendern die SVG-Grafik in den Standardmaßen 300x150px.


Folgende Elemente können das viewBox-Attribut verwenden:

Interaktive viewBox-Demo
(von Sara Soueidan)

Anwendungsbeispiele[Bearbeiten]

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[Bearbeiten]

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.

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[Bearbeiten]

Mit dem preserveAspectRatio-Attribut können Sie das gewünschte Seitenverhältnis festlegen. Bei allen Elementen außer bei image wird preserveAspectRatio ohne ein zuvor gesetztes viewBox-Attribut ignoriert.

Folgende Angaben sind möglich:

  • align:
    • none - keine gleichmäßige Skalierung. Die viewBox wird in X- und Y-Richtung ohne Rücksicht auf das Seitenverhältnis gestreckt, so dass sie das svg-Element ausfüllt.
    • xMinYMin - erzwinge gleichmäßiges Skalieren.
      Richte <min-x> der viewBox mit dem kleinsten X-Wert des Viewports aus.
      Richte <min-y> der viewBox am kleinsten Y-Wert des Viewports aus.
    • xMidYMin - erzwinge gleichmäßiges Skalieren.
      Richte den mittleren X-Wert der viewBox am mittleren X-Wert des Viewports aus.
      Richte <min-y> der viewBox am kleinsten Y-Wert des Viewports aus.
    • xMaxYMin - erzwinge gleichmäßiges Skalieren.
      Richte <min-x>+<width> der viewBox am maximum X-Wert des Viewports aus.
      Richte <min-y> der viewBox am kleinsten Y-Wert des Viewports aus.
    • xMinYMid - erzwinge gleichmäßiges Skalieren.
      Richte <min-x> der viewBox am kleinsten X-Wert des Viewports aus.
      Richte den mittleren Y-Wert der viewBox am mittleren Y-Wert des Viewports aus.
    • xMidYMid (Standardwert) - erzwinge gleichmäßiges Skalieren.
      Richte den mittleren X-Wert der viewBox am mittleren X-Wert des Viewports aus.
      Richte den mittleren Y-Wert der viewBox am mittleren Y-Wert des Viewports aus.
    • xMaxYMid - erzwinge gleichmäßiges Skalieren.
      Richte <min-x>+<width> der viewBox am maximum X-Wert des Viewports aus.
      Richte den mittleren Y-Wert der viewBox am mittleren Y-Wert des Viewports aus.
    • xMinYMax - erzwinge gleichmäßiges Skalieren.
      Richte <min-x> der viewBox mit dem kleinsten X-Wert des Viewports aus.
      Richte <min-y>+<height> der viewBox am maximum Y-Wert des Viewports aus.
    • xMidYMax - erzwinge gleichmäßiges Skalieren.
      Richte den mittleren X-Wert der viewBox am mittleren X-Wert des Viewports aus.
      Richte <min-y>+<height> der viewBox am maximum Y-Wert des Viewports aus.
    • xMaxYMax - erzwinge gleichmäßiges Skalieren.
      Richte <min-x>+<width> der viewBox am maximum X-Wert des Viewports aus.
      Richte <min-y>+<height> der viewBox am maximum Y-Wert des Viewports aus.
  • meetOrSlice - diese Zusatzangabe ist nur sinnvoll, wenn der Wert für align nicht none ist:
    • meet - verkleinere die viewBox so weit, dass sie vollständig im svg-Element sichtbar ist. Ist sie vom Seitenverhältnis her zu breit, entsteht über oder unter ihr Leerraum. Ist sie zu hoch, entsteht der Leerraum neben ihr.
    • slice - skaliere die Viewbox so, dass kein Leerraum entsteht. Ist sie vom Seitenverhältnis her zu breit, wird links bzw. rechts abgeschnitten. Ist sie zu hoch, wird unten bzw. oben abgeschnitten.

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.

Praxis[Bearbeiten]

padding-bottom height fix[Bearbeiten]

Um inline-SVG auch im Internet Explorer 9-11 responsiv zu skalieren, können Sie ein Container-Element um das svg-Element legen.


.skalierender-svg-container {
 position: relative; 
 height: 0; 
 width: 100%; 
 padding: 0;
 padding-bottom: 100%; /* override this inline for aspect ratio other than square */
}
.skalierendes-svg {
 position: absolute; 
 height: 100%; 
 width: 100%; 
 left: 0; 
 top: 0;
}
</svg>
<div class="skalierender-svg-container" 
   style="padding-bottom: 71.5% /* 100% * 500/700 */">
  <svg class="skalierendes-svg" 
       viewBox="0 0 700 500" >
    <!-- SVG Inhalt -->
  </svg>
</div>
Das div wird von allen Browsern genau quadratisch dargestellt, da sich der Wert für padding-bottom von der Breite des Elements ableitet. Wenn es skaliert wird, behält es seine Proportionen.
Beachten Sie: Dieser Hack hat mehrere Nachteile. Zum einen benötigt man ein zusätzliches Element, zum anderen muss der padding-bottom bei einer Änderung der Seitenproportionen neu angepasst werden.
Wenn das Elternelement display: flex gesetzt hat, ist das berechnete padding-bottom = 0, sodass der Hack unwirksam bleibt.




Weblinks[Bearbeiten]

deutsch

Quellen[Bearbeiten]

  1. W3C: ViewBoxAttribute