How to Scale SVG

Avatar of Amelia Bellamy-Royds
Amelia Bellamy-Royds am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Das Folgende ist ein Gastbeitrag von Amelia Bellamy-Royds. Amelia hat viel Erfahrung mit SVG, als Co-Autorin von SVG Essentials und Autorin des kommenden Using SVG with CSS3 and HTML5. Amelia und ich werden beide auf dem kommenden RWD Summit über SVG sprechen! Hier teilt sie einen epischen Leitfaden zum Skalieren von SVG, der alle gewünschten Wege abdeckt. Es ist nicht annähernd so einfach wie das Skalieren von Rastergrafiken, aber das kann gut sein, da es interessante Möglichkeiten eröffnet.

Du hast die Entscheidung getroffen. Du wirst es endlich tun. Dieses Jahr wirst du anfangen, SVG in deinen Webdesigns zu verwenden. Du erstellst ein fabelhaftes Header-Logo in Inkscape und kopierst den SVG-Code, den es ausgibt, in deine WordPress-Header-Datei. Natürlich gibst du deine Auflösung vom letzten Jahr, immer Responsive Design zu nutzen, nicht auf, also setzt du svg.banner { width: 100%; height: auto; } in deinem CSS und denkst, du bist fertig.

Bis du deine Webseite in Testbrowsern öffnest und feststellst, dass einige riesige Blöcke von Weißraum oberhalb und unterhalb des Bildes hinterlassen, während andere es zu kurz beschneiden.

SVG steht für Scalable Vector Graphics. Das Skalieren von SVG sollte also einfach sein, oder? Das haben die SVG-Befürworter doch die ganze Zeit gesagt, dass SVG in jeder Größe gut aussieht? Das ist es, aber doch auch nicht. SVG sieht in jeder Größe großartig aus, aber es kann auf so viele verschiedene Arten skaliert werden, dass es für SVG-Anfänger verwirrend sein kann, es genau so verhalten zu lassen, wie du es möchtest. Es hilft auch nicht, dass Browser erst seit kurzem einen Standardansatz für die Größenanpassung von Inline-SVG-Inhalten übernommen haben.

SVG ist nicht (nur) ein Bild

Ein Grund dafür, dass das Skalieren von SVG so schwierig ist, liegt darin, dass wir eine bestimmte Vorstellung davon haben, wie Bilder skalieren sollten, und SVG verhält sich nicht auf die gleiche Weise.

Rasterbilder wie JPG, PNG und GIF haben eine klar definierte Größe. Die Bilddatei beschreibt, wie der Browser ein Raster einfärben soll, das eine bestimmte Anzahl von Pixeln breit und eine bestimmte Anzahl von Pixeln hoch ist. Eine wichtige Nebenwirkung ist, dass Rasterbilder ein klar definiertes Seitenverhältnis haben: das Verhältnis von Breite zu Höhe.

Man kann den Browser zwingen, ein Rasterbild in einer anderen Größe als seiner intrinsischen Höhe und Breite zu zeichnen, aber wenn man es zu einem anderen Seitenverhältnis zwingt, werden die Dinge verzerrt. Aus diesem Grund gibt es seit den frühen Tagen des Webs die Unterstützung für die auto-Skalierung bei Bildern: Man setzt die Höhe oder die Breite, und der Browser passt die andere Dimension an, damit das Seitenverhältnis konstant bleibt.

Das Skalieren von Rasterbildern gilt auch, wenn sie als background-image verwendet werden, nur dass wir die object-fit-Eigenschaft zur Größenanpassung und zum Beschneiden verwenden.

SVG-Bilder hingegen können in jeder Pixelgröße gezeichnet werden, daher benötigen sie keine klar definierte Höhe oder Breite. Und sie haben nicht immer ein klar definiertes Seitenverhältnis. Du musst diese Informationen (und mehr) explizit angeben, wenn das SVG so skaliert werden soll, dass es sich an die von dir vorgegebenen Dimensionen anpasst.

Wenn du das nicht tust, skaliert SVG überhaupt nicht. Das folgende Beispiel verwendet Inline-SVG und passt die Dimensionen des Elements (gestrichelte Linie) an, ohne die Größe der gezeichneten Grafik zu verändern

Warum verhält es sich so? Weil SVG nicht (nur) ein Bild ist. SVG ist ein Dokument. Obwohl das obige Beispiel Inline-SVG verwendet, könnte es genauso gut <object> oder <iframe> verwendet haben. Es würde genauso aussehen, selbst wenn du <img>-Tags verwenden würdest, um denselben SVG-Code einzubetten.

Wenn du eine HTML-Datei mit einem <iframe> inkludierst, erwartest du nicht, dass sich der Text darin skaliert, wenn du die Größe des Rahmens änderst. Dasselbe gilt für SVG. Standardmäßig wird es in der im Code angegebenen Größe gezeichnet, unabhängig von der Größe der Zeichenfläche. Was passiert, wenn du die Höhe oder Breite (oder beides) auf auto für diese SVGs setzt? Es wird die Standardgröße für ersetzte HTML-Elemente verwendet: 300px breit, 150px hoch. Das gilt für <img><object> oder <iframe>. Die Standardgröße von 300×150 gilt auch für Inline-<svg>-Elemente innerhalb von HTML-Dokumenten, aber das ist ein relativ neuer Konsens aus den HTML5-Spezifikationen: Andere Browser skalieren Inline-SVG standardmäßig auf die volle Größe des Viewports — äquivalent zu width: 100vw; height: 100vh; — was die Standardgröße für SVG-Dateien ist, die direkt in ihrem eigenen Browser-Tab geöffnet werden. Internet Explorer halbiert die Differenz und verwendet eine Breite von 100 % und eine Höhe von 150 px für Bilder und Inline-SVG.

Mit anderen Worten, selbst wenn du denkst, 300×150 sei eine perfekte Bildgröße (obwohl warum solltest du das tun?), verlasse dich nicht auf eine Standardgröße für <svg> in HTML.

Zusätzlich zur Entscheidung, welche Größe dein SVG haben soll, musst du dich auch entscheiden, wie dein Grafik sich an diese Größe anpassen soll. Unten beschreibe ich den Code, den du benötigst, um die Skalierung zu erreichen, die du für die häufigsten Situationen wünschst

  • Skalieren, um sich an eine bestimmte Größe anzupassen, ohne das Bild zu verzerren
  • Skalieren, um sich an eine bestimmte Größe anzupassen, wobei die Grafik nach Bedarf gedehnt oder gestaucht wird
  • Skalieren, um sich an die verfügbare Breite anzupassen, während das Seitenverhältnis von Breite zu Höhe beibehalten wird
  • Nicht-uniformes Skalieren, so dass sich einige Teile der Grafik anders skalieren als andere

Aber zuerst: Wenn du die Skalierung deines SVG kontrollieren möchtest, musst du dich mit den SVG-Skalierungsattributen und anderen verfügbaren Werkzeugen vertraut machen.

Die SVG-Skalierungs-Werkzeugkiste

Andere Bilder skalieren, weil der Browser die Höhe, Breite und das Seitenverhältnis des Bildes kennt und alles zusammen anpasst. SVG diese Eigenschaften zu geben, ist der erste Schritt, um es zum Skalieren zu bringen. Das Skalieren von SVG geht jedoch über das hinaus, was mit anderen Bildern möglich ist.

Die Attribute height und width

Ein erster Blick auf die SVG-Spezifikationen würde vermuten lassen, dass die Attribute height und width auf dem obersten svg-Element implizit ein Seitenverhältnis festlegen und SVG daher wie andere Bilder skalieren lassen. Es stimmt, dass das Setzen von Höhe und Breite die Standarddimensionen überschreibt, wenn man SVG als Bild verwendet. Aber natürlich ist es nicht so einfach.

  • Wenn du ein <img> verwendest, um dein SVG einzubetten, bewirkt das Setzen von height und width, dass sich das SVG in den meisten Browsern vorhersagbar skaliert, aber nicht in Internet Explorer. Mit CSS wie img { width: 100%; height: auto; } skaliert IE den Bildbereich automatisch, um das Breiten-Höhen-Seitenverhältnis konstant zu halten, skaliert aber nicht die eigentliche Zeichnung, um die Skalierung der Bildabmessungen anzupassen.
  • Wenn du ein <object><embed> oder <iframe> verwendest, um dein SVG einzubetten, ändert das Setzen von Höhe und Breite auf dem <svg> nicht die Größe des Rahmens; du erhältst einfach Scrollbalken innerhalb deines Iframes, wenn das SVG zu groß ist.
  • Wenn du Inline-SVG verwendest (d. h. <svg> direkt in deinem HTML5-Code), dann übernimmt das <svg>-Element eine Doppelrolle und definiert sowohl den Bildbereich innerhalb der Webseite als auch innerhalb des SVG. Jede Höhe oder Breite, die du für das SVG mit CSS festlegst, überschreibt die Höhen- und Breitenattribute auf dem <svg>. Eine Regel wie svg {width: 100%; height: auto;} hebt daher die im Code festgelegten Abmessungen und das Seitenverhältnis auf und gibt dir die Standardhöhe für Inline-SVG. Diese wird, wie oben erwähnt, je nach Browser entweder 150px oder 100vh sein.

Also vergiss height und width. Du möchtest tatsächlich nicht die exakte Höhe und Breite festlegen, sondern möchtest, dass sich das SVG an die in CSS festgelegte Breite und/oder Höhe anpasst. Was du möchtest, ist, ein Seitenverhältnis für das Bild festzulegen und die Zeichnung so skalieren zu lassen, dass sie passt. Du möchtest eine viewBox.

Das viewBox-Attribut

Die SVG viewBox ist eine ganze Menge Magie in einem kleinen Attribut vereint. Sie ist das letzte Puzzleteil, das Vektorgrafiken zu Scalable Vector Graphics macht. Die viewBox tut viele Dinge

  • Sie definiert das Seitenverhältnis des Bildes.
  • Sie definiert, wie alle Längen und Koordinaten innerhalb des SVG skaliert werden sollen, um den gesamten verfügbaren Platz auszufüllen.
  • Sie definiert den Ursprung des SVG-Koordinatensystems, den Punkt, an dem x=0 und y=0 ist.

Die viewBox ist ein Attribut des <svg>-Elements. Ihr Wert ist eine Liste von vier Zahlen, getrennt durch Leerzeichen oder Kommas: x, y, Breite, Höhe. Die Breite ist die Breite in Benutzereinheiten/px-Einheiten, innerhalb des SVG-Codes, die auf die Breite des Bereichs skaliert werden soll, in den du dein SVG zeichnest (in SVG-Terminologie das Viewport). Ebenso ist die Höhe die Anzahl der px/Koordinaten, die auf die verfügbare Höhe skaliert werden sollen. Selbst wenn dein SVG-Code andere Einheiten verwendet, wie Zoll oder Zentimeter, werden diese ebenfalls so skaliert, dass sie mit der durch die viewBox geschaffenen Gesamtgröße übereinstimmen.

Die x- und y-Zahlen geben die Koordinate im skalierten viewBox-Koordinatensystem an, die für die obere linke Ecke des SVG-Viewports verwendet werden soll. (Koordinaten nehmen von links nach rechts und von oben nach unten zu, genauso wie bei der Identifizierung von Seitenpositionen in JavaScript). Für einfache Skalierung kannst du beide Werte auf 0 setzen. Die x- und y-Werte sind jedoch für zwei Zwecke nützlich: um ein Koordinatensystem mit einem Ursprung zu schaffen, der in der Mitte der Zeichnung zentriert ist (dies kann die Definition und Transformation von Formen erleichtern), oder um ein Bild enger zuzuschneiden, als es ursprünglich definiert war.

Einige Beispielwerte für viewBox

  • viewBox="0 0 100 100": Definiert ein Koordinatensystem von 100 Einheiten Breite und 100 Einheiten Höhe. Anders ausgedrückt: Wenn dein SVG einen Kreis enthält, der in der Grafik zentriert ist und einen Radius von 50 Pixeln hat, würde dieser die Höhe oder Breite des SVG-Bildes ausfüllen, selbst wenn das Bild im Vollbildmodus angezeigt wird. Wenn dein SVG ein Rechteck mit height="1in" enthält, würde es auch fast den ganzen Bildschirm ausfüllen, da 1 Zoll = 96 Pixel in CSS entspricht und alle Längen gleich skaliert werden.
  • viewBox="5 0 90 100": Ähnliche Ansicht, aber um 5 % von links und rechts beschnitten, so dass die Gesamtbreite = 90 Einheiten und die x-Koordinate links = 5 ist.
  • viewBox="-50 -50 100 100": Eine Ansicht mit der gleichen Skalierung, aber jetzt mit der oberen linken Ecke mit den Koordinaten (-50, -50). Das bedeutet, dass die untere rechte Ecke die Koordinaten (+50, +50) hat. Jede Form, die bei (100, 100) gezeichnet wird, wird weit außerhalb des Bildschirms liegen. Wenn du einen Kreis zeichnen wolltest, der den gesamten Bildbereich ausfüllt, wäre er bei (0, 0) zentriert.

Sobald du deiner <svg> eine viewBox hinzufügst (und Editoren wie Inkscape und Illustrator fügen sie standardmäßig hinzu), kannst du diese SVG-Datei als Bild oder als Inline-SVG-Code verwenden, und sie wird perfekt skaliert, um sich an jede von dir vorgegebene Größe anzupassen. Allerdings wird sie immer noch nicht ganz wie jedes andere Bild skaliert. Standardmäßig wird sie nicht gestreckt oder verzerrt, wenn du ihr Abmessungen gibst, die nicht mit dem Seitenverhältnis übereinstimmen. Stattdessen wird die Skalierung angepasst, um das im Code definierte Seitenverhältnis beizubehalten.

Das preserveAspectRatio-Attribut

Das viewBox-Attribut hat einen Sidekick, preserveAspectRatio. Es hat keine Auswirkung, es sei denn, eine viewBox existiert, um das Seitenverhältnis des Bildes zu definieren. Wenn eine viewBox vorhanden ist, preserveAspectRatio beschreibt, wie das Bild skaliert werden soll, wenn das Seitenverhältnis der viewBox nicht mit dem Seitenverhältnis des Viewports übereinstimmt. Meistens funktioniert das Standardverhalten ziemlich gut: Das Bild wird skaliert, bis es sowohl Höhe als auch Breite ausfüllt, und es wird innerhalb jedes zusätzlichen Raums zentriert.

Genau wie viewBox enthält preserveAspectRatio viele Informationen in einem einzigen Attribut. Das Standardverhalten kann explizit mit preserveAspectRatio="xMidYMid meet" eingestellt werden. Der erste Teil, xMidYMid weist den Browser an, den skalierten viewBox-Bereich sowohl in der x- als auch in der y-Richtung innerhalb des verfügbaren Viewport-Bereichs zu zentrieren. Du kannst Mid durch Min oder Max ersetzen, um die Grafik bündig an einer Seite oder der anderen auszurichten. Achte jedoch auf die Kamelhöcker-Schreibweise: SVG ist XML und daher Groß-/Kleinschreibungsempfindlich. Das x ist klein geschrieben, aber das Y ist groß geschrieben.

Die zweite Hälfte des Standardwerts preserveAspectRatiomeet, ist der Teil, der dem Browser sagt, er soll die Grafik skalieren, bis sie sowohl Höhe als auch Breite ausfüllt. Dies ist bei CSS-Hintergrundbildern äquivalent zu background-size: contain;. Der alternative Wert für SVG ist slice (äquivalent zu background-size: cover;). Ein slice-Wert skaliert das Bild so, dass es sich an die großzügigere Dimension anpasst, und schneidet das Zusätzliche ab. Außer, dass es nicht unbedingt das Zusätzliche abschneidet; das hängt vom Wert der overflow-Eigenschaft ab.

Wenn du möchtest, dass jedes Bild in den von dir vorgegebenen Dimensionen zentriert wird, anstatt gestreckt oder verzerrt zu werden, ermöglicht dir die neue CSS-Eigenschaft object-fit, dies auch mit anderen Bildtypen zu tun.

Es gibt auch die Option preserveAspectRatio="none", um dein SVG genau wie ein Rasterbild zu skalieren (aber mit viel besserer Auflösung), indem es sich an die von dir vorgegebene Höhe und Breite anpasst oder verzerrt.

Wie man SVG an eine bestimmte Größe anpasst (ohne das Bild zu verzerren)

Die wahrscheinlich häufigste Anforderung ist, dass sich ein SVG-Icon an eine bestimmte Größe anpasst, ohne Verzerrung. Das viewBox-Attribut ist hierfür eigentlich alles, was du brauchst, obwohl du preserveAspectRatio verwenden kannst, um die Ausrichtung anzupassen.

Wie bereits erwähnt, enthält deine SVG, wenn du sie in einem Grafikeditor erstellst, wahrscheinlich bereits eine viewBox. Möglicherweise möchtest du die viewBox jedoch anpassen, um die Positionierung genau richtig hinzubekommen. Die Topf-des-Goldes-Grafik hat für die restlichen Beispiele eine viewBox="0 0 60 55" erhalten. Das lässt etwas zusätzlichen Platz darum herum; um ein eng beschnittenes Icon zu erstellen, könntest du viewBox="4.5 1.5 51 49" verwenden. Das folgende Beispiel zeigt auch die Auswirkung des Standardwerts preserveAspectRatio, der die Grafik in dem bereitgestellten Raum zentriert

Wie man SVG an die verfügbare Breite anpasst (und die Höhe entsprechend anpasst)

SVG mit einer viewBox wird an die Höhe und Breite angepasst, die du vorgibst. Aber was ist mit der automatischen Größenanpassung? Bei Rasterbildern kannst du width oder height setzen und die andere Seite anpassen lassen. Kann SVG das?

Das kann es, aber es wird kompliziert. Es gibt ein paar verschiedene Ansätze zur Auswahl, je nachdem, wie du dein SVG einbindest.

Option 1: Automatische Größenanpassung des Bildes verwenden

Wenn eine SVG-Datei eine viewBox hat und in einem <img> eingebettet ist, skalieren Browser (fast immer) das Bild, um es an das in der viewBox definierte Seitenverhältnis anzupassen.

Internet Explorer bleibt jedoch der Fluch von SVG. Obwohl er normalerweise gut funktioniert, habe ich display: table-cell verwendet, um die Figuren in einer früheren Version dieses Beispiels anzuordnen, und IE hat die Bilder auf seltsame Weise verzerrt.

Wenn du das Bild komplett automatisch skalierst, wendet Internet Explorer die standardmäßige Standardgröße von 300×150 an. Andere Browser wenden jedoch standardmäßig { width: 100%; height: auto; } an, wenn das Bild eine viewBox hat; dieses Verhalten ist in keiner Spezifikation definiert.

Zusammenfassend lässt sich sagen: Um SVG, das als <img> verwendet wird, automatisch zu skalieren,

  1. Setze ein viewBox-Attribut.
  2. Setze mindestens eine der Optionen Höhe oder Breite.
  3. Platziere es nicht innerhalb eines Tabellenlayouts, wenn du Internet Explorer unterstützen möchtest.

Option 2: CSS-Hintergrundbilder und der padding-bottom Hack

Größtenteils funktioniert die Verwendung von SVG als CSS-Hintergrundbild viel wie die Verwendung in einem <img> (aber mit dem zusätzlichen Vorteil, dass man Raster-Fallbacks für alte Browser definieren kann). Es gibt einige Fehler bei älteren Browsern, die das Bild nach der Konvertierung in Raster skalieren, anstatt davor (d. h. es verpixelt), aber im Großen und Ganzen ist die viewBox alles, was du brauchst.

Allerdings ist die automatische Größenanpassung keine Option für CSS-Hintergrundbilder; schließlich ist das Bild sekundär zum HTML-Inhalt des Elements. Wenn du möchtest, dass das Element exakt das Seitenverhältnis des von dir verwendeten Bildes hat, musst du es ein wenig hacken.

Es gibt eine Auswahl von CSS-Eigenschaften, die es dir ermöglichen, höhenbasierte Attribute basierend auf der verfügbaren Breite anzupassen. Wenn du den borderpadding oder margin eines Blocklayout-Elements auf Prozentwerte setzt, werden die Prozente relativ zur verfügbaren Breite des Containers berechnet, selbst für die oberen und unteren Ränder, Abstände und Ränder.

Der beabsichtigte Zweck ist es, gleichmäßig große Ränder und Abstände zu schaffen, auch wenn die Höhe automatisch ist. Aber das ist nebensächlich. Für unsere Zwecke ist der entscheidende Punkt, dass du die Gesamthöhe eines Elements proportional zur Breite anpassen kannst. Mit anderen Worten, du kannst das Seitenverhältnis kontrollieren. Um ein <div> mit 100 % Breite zu erstellen, das exakt dem 4:3-Seitenverhältnis eines Bildes entspricht, das du als Hintergrund verwendest, kannst du Folgendes verwenden

.ratio4-3 {
 width: 100%;
 background-image: url(image-with-4-3-aspect-ratio.svg);
 background-size: cover;
 height: 0;
 padding: 0; /* reset */
 padding-bottom: calc(100% * 3 / 4);
}

Zu beachtende Punkte

  • Um die gewünschte Höhe als Prozentsatz der verfügbaren Breite zu erhalten, multipliziere die prozentuale Breite mit dem gewünschten Höhenfaktor, geteilt durch den gewünschten Breitenfaktor.
  • Wenn du Browser unterstützen möchtest, die calc() nicht unterstützen, musst du die Mathematik selbst (oder mit einem CSS-Präprozessor) durchführen.
  • Wenn du standardmäßig jedes Element auf box-sizing: border-box setzt, musst du es zurück auf box-sizing: content-box setzen. Wir wollen ja, dass es height: 0 plus Padding ist.
  • Die Eigenschaft padding-bottom wird anstelle von padding-top verwendet wegen Problemen in IE5. Auch wenn du wahrscheinlich nicht vorhast, IE5 zu unterstützen, kannst du genauso gut konsistent sein. Es wird schließlich der padding-bottom Hack genannt.

Für das Topf-des-Goldes-Bild war das Seitenverhältnis 60:55, was einem unteren Padding von 92 % entspricht. In Aktion sieht das so aus

Option 3: Inline SVG und die neuesten Blink/Firefox-Browser verwenden

SVG-Bilder sind nett, aber in vielen Fällen wirst du Inline-SVG bevorzugen. Inline-SVG reduziert die Anzahl der HTTP-Anfragen, ermöglicht Benutzerinteraktionen und kann durch das CSS deiner Hauptwebseite modifiziert werden. Aber wird es skalieren?

Das wird es, wenn du die neuesten Firefox- oder Blink-Browser verwendest. Setze einfach die viewBox auf dein <svg> und setze eine der Optionen Höhe oder Breite auf auto. Der Browser wird sie so anpassen, dass das Gesamtseitenverhältnis mit der viewBox übereinstimmt. Wunderschön.

Aber wahrscheinlich musst du nicht nur diese Browser unterstützen.

Viele Browser — IE, Safari und Versionen von Opera und Chrome, die vor Sommer 2014 veröffentlicht wurden — skalieren Inline-SVG nicht automatisch. Wenn du nicht sowohl Höhe als auch Breite angibst, wenden diese Browser ihre üblichen Standardgrößen an, die, wie bereits erwähnt, je nach Browser unterschiedlich sind. Das Bild wird skaliert, um in diese Höhe oder Breite zu passen, und lässt wieder zusätzlichen Weißraum darum herum. Auch hier gibt es Inkonsistenzen, was passiert, wenn du sowohl Höhe als auch Breite auf auto lässt.

Die Lösung ist wieder der padding-bottom Hack, um das Seitenverhältnis selbst zu steuern. Der einfachste Ansatz, der sowohl für Inline-SVG als auch für <object><iframe> und andere ersetzte Elemente wie <video> funktioniert, ist die Verwendung eines Container-Elements.

Option 4: Den padding-bottom Hack auf einem Container verwenden

Um einen Container <div> zu verwenden, füge Klassen oder Inline-Stile zum Div hinzu, um ihm das richtige Seitenverhältnis zu geben, wie oben bei der Verwendung eines Hintergrundbildes geschehen. Aber setze auch position: relative auf den Container, damit er zum Referenzrahmen für absolut positionierte Inhalte wird. Dann setze das SVG (oder ein anderes Objekt) auf position: absolute, mit Höhe und Breite von 100 %. Die absolute Positionierung ist erforderlich, damit die Prozente relativ zur Höhe des <div> berechnet werden, einschliesslich des Paddings, und nicht relativ zum nullhohen Inhaltsbereich.

Es sei denn, du hast viele Grafiken mit demselben Seitenverhältnis, ist es normalerweise sinnvoll, das padding-bottom inline zu deklarieren, damit es sich direkt neben der viewBox befindet, die es abgleichen muss

<div class="scaling-svg-container" 
   style="padding-bottom: 92% /* 100% * 55/60 */">
  <svg class="scaling-svg" viewBox="0 0 60 55">
    <!-- SVG content -->
  </svg>
</div>
.scaling-svg-container {
 position: relative; 
 height: 0; 
 width: 100%; 
 padding: 0;
 padding-bottom: 100%; 
 /* override this inline for aspect ratio other than square */
}
.scaling-svg {
 position: absolute; 
 height: 100%; 
 width: 100%; 
 left: 0; 
 top: 0;
}

Der Container-Ansatz funktioniert, aber auf Kosten eines zusätzlichen Wrapper-Elements in deinem Markup. Und es ist auch kein Allzweck-Container: Es ist ein Container, der an das exakte Seitenverhältnis angepasst werden muss, das dein SVG benötigt. Die Dinge werden noch kniffliger, wenn du nicht möchtest, dass er auf volle 100 % skaliert; du benötigst einen weiteren Wrapper <div>, um die gewünschte Breite und andere Positionierungsattribute festzulegen. Ich persönlich würde es vorziehen, alle Informationen über das SVG-Seitenverhältnis im SVG-Code selbst zu belassen. Um dies für Inline-SVG zu tun, musst du dem Browser sagen, dass er ausserhalb der Linien und in das Padding zeichnen soll.

Option 5: Den padding-bottom Hack auf einem Inline <svg>-Element verwenden

Um den padding-bottom Hack zu verwenden, um das Seitenverhältnis des gesamten <svg>-Bereichs zu steuern, wird die offizielle Höhe (im Wesentlichen) Null sein. Mit dem Standardwert von preserveAspectRatio würde die Grafik auf Null skaliert werden. Stattdessen möchtest du, dass deine Grafik die gesamte Breite, die du ihr gibst, ausfüllt und über den Padding-Bereich hinausgeht, den du sorgfältig auf das richtige Seitenverhältnis eingestellt hast.

Auch hier verwende ich gerne Inline-Stile für das padding-bottom-Seitenverhältnis, da es an das viewBox-Attribut angepasst werden muss. Im folgenden Beispiel verwende ich es auch für die anderen Stileigenschaften, obwohl du auch eine Klasse verwenden könntest, wenn du viele Grafiken hast, die die gleichen Effekte benötigen

<svg viewBox="0 0 60 55" preserveAspectRatio="xMidYMin slice"
   style="width: 100%; padding-bottom: 92%; height: 1px; overflow: visible">
  <!-- SVG content -->
</svg>

Dabei gibt es noch ein paar weitere Details

  • Die Höhe ist 1px, nicht 0, sonst wird das SVG möglicherweise nicht gezeichnet (Firefox) oder skaliert nicht (Chrome).
  • Die preserveAspectRatio verwendet YMin für die vertikale Ausrichtung, so dass die Grafik sauber am oberen Rand des <svg> Inhaltsbereichs ausgerichtet ist und in das untere Padding überläuft.
  • Obwohl overflow: visible bei HTML Standard ist, muss es für SVG explizit gesetzt werden.

Wenn du möchtest, dass das SVG auf einen Prozentsatz von weniger als 100 % Breite skaliert wird, denke daran, padding-bottom entsprechend anzupassen. Oder verwende einen Wrapper <div>, um die Größe festzulegen.

Wie man SVG skaliert, streckt und quetscht, um sich exakt an eine bestimmte Größe anzupassen

Obwohl die Beibehaltung des Seitenverhältnisses normalerweise wünschenswert ist, handelt es sich manchmal um ein abstraktes oder flexibles Bild, das du strecken möchtest, um es anzupassen.

Option 1: Prozente verwenden

Eine Möglichkeit, um zu strecken und anzupassen, ist die Verwendung von Prozentwerten für alle Größen- und Positionsattribute im SVG.

Zu beachtende Punkte zu Prozenten und SVG

  • Wenn du Prozente zum Strecken und Stauchen verwendest, füge keine viewBox hinzu (obwohl du Standardhöhe und -breite angeben kannst).
  • Einige Längen in SVG sind nicht klar entweder der Höhe oder der Breite zugeordnet; zum Beispiel der Radius eines Kreises. Wenn du in diesen Fällen Prozentwerte verwendest, wird die Länge als geometrisches Mittel (Quadratwurzel der Summe der Quadrate, geteilt durch die Quadratwurzel von 2) des entsprechenden Prozentsatzes von Höhe und Breite berechnet. Dies bewahrt die Beziehung des Satzes des Pythagoras von Diagonalen zu Rechtecklinien, ist aber ansonsten etwas verwirrend.
  • Viele Längen in SVG können nicht mit Prozenten angegeben werden, am wichtigsten sind die Koordinaten von <path> und <polygon>-Elementen.

Option 2: preserveAspectRatio="none" verwenden

Wenn Sie eine flexibel skalierbare SVG-Datei wünschen, die auch SVG-Pfade enthält, benötigen Sie eine viewBox plus preserveAspectRatio="none". Hier ist eine etwas schickere Version dieses Regenbogens mit flauschigen Wolken.

Seien Sie sich bewusst, dass mit preserveAspectRatio="none" alles gleichmäßig gestreckt oder gequetscht wird, so als würden Sie andere Bildtypen ungleichmäßig skalieren. Das bedeutet, dass Kreise zu Ellipsen gestreckt werden und Text verzerrt wird. Um dies zu vermeiden, müssen Sie eine Mischung aus Skalierungsansätzen verwenden.

Teile einer SVG separat skalieren

Die Attribute viewBox und preserveAspectRatio sind unglaublich flexibel. Sobald Sie aufhören, SVG als nur ein weiteres Bildformat zu betrachten, können Sie sich fragen, *wie* Ihre Grafik beim Ändern der Fenstergröße skalieren soll.

Wichtig ist zu erkennen, dass Sie nicht für die gesamte SVG eine einzige viewBox und preserveAspectRatio Option definieren müssen. Stattdessen können Sie verschachtelte <svg>-Elemente verwenden, jedes mit seinen eigenen Skalierungsattributen, um verschiedene Teile Ihrer Grafik unabhängig voneinander skalieren zu lassen. (Sie können diese Attribute auch für <symbol> und <pattern>-Elemente verwenden, und Sie können preserveAspectRatio für andere in Ihre SVG eingebettete Bilder verwenden.) Mit diesem Ansatz können Sie eine Kopfzeilengrafik erstellen, die sich streckt, um ein Breitbilddisplay auszufüllen, ohne übermäßige Höhe einzunehmen.