Adaptive SVG-Datei mit unterschiedlichen Seitenverhältnissen

SVG responsive

SVG-Grafiken sind responsiv und passen sich geschmeidig an den verfügbaren Platz an. Mit wenig Mehraufwand kann eine SVG-Datei mehr Elemente für große Viewports, weniger Elemente und ein anderes Seitenverhältnis für kleine Viewports enthalten. CSS und SVG ändern auch das Seitenverhältnis, ohne auf Javascript angewiesen zu sein.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Responsive SVG-Dateien

SVG-Dateien können sich nicht nur je nach Größe des Viewports ausdehnen und schrumpfen, sondern Grafiken in verschiedenen Seitenverhältnissen aufnehmen. Dabei muss nicht einmal die Dateigröße zunehmen, sondern SVG symbol und use bewältigen unterschiedliche Seitenverhältnisse ohne Beistand von Javascript. Selbst der Aufwand für das CSS in der HTML-Datei beschränkt sich auf wenige Zeilen.

So gut sich SVG auch an den verfügbaren Platz anpasst, macht es nicht immer Sinn, die Grafik in einen kleinen Raum zu quetschen. Während das HTML-picture-Element Varianten eines Bildes anhand von zwei, drei oder mehr Bitmap-Dateien setzt, bleiben alle Komponenten einer adaptiven SVG-Grafik in einer Datei.

Browserfenster kleiner oder größer aufziehen
Bildquelle: Python Programming Language Logo, auf Wikipedia

Die SVG-Datei nutzt symbol- und use- Elemente, um sowohl die lange Form des Python-Logos als auch das Quadrat mit dem grafischen Logo ohne Text unterzubringen.

SVG-Datei
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="python" viewBox="0 0 600 200">
	<path id="bluePhy" fill="navy" d="m60.51 6.398c-4.584 …" />
	<path id="yellowPhy" fill="gold" d="m91.23 35 " />
	<path id="p" d=" … " />
	<path id="y" d=" … " />
	…
</symbol>

<symbol id="logo" viewBox="0 0 120 120">
	<use href="#bluePhy" />
	<use href="#yellowPhy" />
</symbol>
</svg>

Das HTML setzt beide Varianten als SVG-Elemente mit use und Pfadangabe. Das jeweilige symbol-Element wird über ein "#" angesprochen. Mit einer einfach Media Query entscheidet das CSS, welche der beiden Komponenten angezeigt und welche mit display: none ausgeblendet wird.

CSS
@media (max-width: 919px) {
	.large { display: none}
}

@media (min-width: 920px) {
	.quart { display: none}
}
HTML
<div class="quart">
	<svg width="100%" height="100%">
		<use href="svg/python.svg#logo" />
	</svg>
</div>

<div class="large">
	<svg width="100%" height="100%">
		<use href="svg/python.svg#python" />
	</svg>
</div>

SVG inline

Mehr oder weniger Elemente einer SVG-Grafik je nach Größe des Viewports ist einfach, wenn das SVG inline gesetzt wird und das Seitenverhältnis der Grafik gleich bleibt. Eine Zeile CSS reicht, um den Text auf kleinen Monitoren auszublenden.

CSS der HTML-Datei
@media (max-width: 599px) {
   .logo { width: 200px}
   .text-on { display: none}
}

@media (min-width: 600px) {
   .logo { width: 300px}
}

SVG als background-image

Hier wird's einen Hauch trickreich. Jetzt braucht die SVG-Datei selber ein paar Zeilen CSS – kein Problem, denn das style-Element wirkt auch bei SVG.

SVG-Datei
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 150 150">
<style>
@media (width: 200px) {
  .textinside {display: none;}
  .colorcircle { fill: cornsilk}
}

@media (width: 300px) {
  .colorcircle { fill: cornflowerblue}
}
</style>
… 

<circle class="colorcircle" cx="75" cy="75" r="75"/>

<text class="textinside" font-size="21px">
   <textPath xlink:href="#textpath">
      <tspan>Javascript if then else</tspan>
   </textPath>
</text>
</svg>

Die Media Query in der SVG-Datei fragt nicht nach der verfügbaren Bildschirmbreite, sondern nach dem verfügbaren Platz im Einsatzgebiet, also im HTML. Darum lautet die Abfrage nicht @media (min-width: 200px), sondern nur @media (width: 200px).

Dazu kommt jetzt das CSS in der HTML-Datei.

CSS der HTML-Datei
<style>
.logobackground { 
   background-image: url(two-snakes-circle.svg); 
   margin: 1em auto;
}
	
@media (max-width: 599px) {
   .logobackground { 
      background-size: 200px;
      width: 200px; 
      height: 200px; 
	}
}

@media (min-width: 600px) {
   .logobackground { 
      background-size: 300px;
      width: 300px; 
      height: 300px; 
   }
}
</style>

CSS background-size ist der Eckpfeiler für die Anzeige der SVG-Grafik als Hintergrundbild.

Seitenverhältnis ändern: SVG in einem iframe laden

Soll die SVG-Grafik als Hintergrundbild oder Grafik geladen werden, kann Javascript nicht eingesetzt werden, um das Seitenverhältnis zu ändern. Externe SVG-Dateien können aus Sicherheitsgründen kein Javascript ausführen oder selber externe Dateien laden.

Wenn es sich nur um eine kleine SVG-Datei handelt, ist Inline-SVG mit Javascript der einfachste Weg, das Seitenverhältnis zu ändern. Soll das SVG aber unter keinen Umständen in der HTML-Datei geladen werden, bleibt noch der Umweg über ein HTML iframe.

In der iframe-Datei sitzt das SVG inline, gefolgt von dem kleinen Javascript zur Anpassung des viewBox-Attributs.

CSS der HTML-Datei
iframe {
   overflow: hidden;   /** Keine Laufleisten **/
   border: none;       /** Kein Rand         **/
}
@media (max-width: 599px) {
   iframe { width: 200px; height: 200px}
}
@media (min-width: 600px) {
   iframe { width: 600px; height: 182px}
}
iframe mit SVG und Javascript
<style>
   svg { width: 100%; height: auto; }
</style>

<body>
<svg width="100%" height="100%" viewBox="0 0 500 150">
…
</svg>

<script>
const long = document.querySelector ('svg');
const mql = window.matchMedia("(min-width:600px)");

clipImage(mql);

mql.addListener(clipImage);

function clipImage(mql) {
   if (mql.matches) {
      long.setAttribute('viewBox','0 0 500 150');
   } else {
      long.setAttribute('viewBox','0 0 150 150');
   }
}
</script>

</body>
SVG RESPONSIVE Kopfüber