Responsive Image Sprites

Responsive Image Sprites

Ein Image Sprite setzt mehrere kleine Bilder in eine Bildatei. So lädt der Browser mit einem HTTP-Request ein einziges Bild anstelle vieler kleiner Bilder mit vielen HTTP-Requests, um Bandbreite zu sparen.

18-12-15 SITEMAP

Ein Bild mit vielen Bildern

Sprites sind eine alte Technik der Grafik: Ein Bild wird einmal geladen, aber zu jedem Zeitpunkt oder an jeder Position nur in Teilen angezeigt. Das Bild muss nur einmal geladen werden und liegt im Cache. CSS Image Sprites und SVG Image Sprites sind die Platzanweiser für die Einzelbilder.

CSS-Image Sprites beschleunigen den Ladevorgang: Nur ein großes Bild laden ist schneller als das Laden vieler kleiner Bilder.

 food-painted-1500.png200 KB
 food-painted-03-50084 KB
 food-painted-01-50075 KB
 food-painted-02-50055 KB

Der Unterschied fällt eher homöopathisch aus, dennoch lohnt sich das Verfahren, denn anstelle von drei gibt es nur noch einen HTTP-Request. Auch mit HTTP/2 kann sich das Verfahren bei vielen sehr kleinen Bildern noch lohnen, obwohl HTTP/2 mit weniger Overhead kommt.

CSS Image Sprites

Die Technik der CSS Image Sprites ist bekannt und bewährt, aber jede Serie braucht ihren eigenen Eintrag in die CSS-Datei. Natürlich gibt es inzwischen Verfahren, um Image Sprites responsive zu machen, die allerdings durch die Berechnung von padding-bottom (dem Seitenverhältnis der Einzelbilder) ganz schön fummelig sind.

.sprites {
   width:30%;
   height: 0;
   padding-bottom: 20%;
   background-size: 300%;
   display:block;
   background-image: url("hot-dog.jpg");
   background-repeat: no-repeat;
}
.sprite-1 {background-position: 0 0;}
.sprite-2 {background-position: 50% 0;}
.sprite-3 {background-position: 100% 0;}

Damit Image Sprites responsive werden, müssen alle Größen in Prozent angegeben werden.

SVG Image Sprites

SVG rendert Bitmap-Bilder in einem SVG image-Tag, das kaum anders aussieht als ein HTML-img-Tag. SVG ist durch sein viewBox-Attribut von Haus aus anpassungsfähig, aber Internet Explorer 10 und 11 lernen das Rechnen auch im hohen Alter nicht mehr.

<svg viewBox="0 0 500 428">
   <image id="pixl" height="428" width="1500" y="0" x="0" xlink:href="fraisier.jpg"/>
</svg>

In einer idealen Welt würden diese drei Zeilen SVG mit einem image-Tag schon reichen. Für IE 11 kommt noch ein HTML-canvas dazu, denn IE11 passt HTML canvas-Elemente beim Vergrößern / Verkleinern im korrekten Seitenverhältnis an, während IE11 einem SVG-Elemente höchstens 215px Höhe gönnt und dann das SVG im korrekten Seitenverhältnis in diese 215px Höhe quetscht.

CSS für responsives SVG für IE11 via canvas

Das canvas-Element wird zum Platzanweiser.

<div class="svginside" style="max-width:400px">
   <canvas width="500" height="428"></canvas>
   <svg viewBox="0 0 500 428">
      <image id="pixl" height="428" width="1500" y="0" x="0" xlink:href="fraisier.jpg"/>
   </svg>
</div>

Das canvas-Element wird mit visibility:hidden; versteckt, das svg-Element absolut oben links positioniert.

.svginside { position:relative; }
.svginside canvas {
   width: 100%;
   visibility:hidden;
   display:block;
}
.svginside svg {
   position: absolute;
   top: 0; left: 0;
   width: 100%;
}

Diese drei CSS-Regeln gehen in die CSS-Datei und alle Image-Sprites greifen darauf zurück. Wird eine Image-Sprite-Serie aus dem HTML gelöscht, muss die CSS-Datei ebenso wenig angefasst werden wie beim Einsetzen weiterer Image Sprites.

Zur Sache: Jetzt noch die SVG-Sprite-Technik

Die Bitmap-Bilder werden genauso wie bei CSS-Image-Sprites nach links aus dem sichtbaren Ausschnitt herausgezogen. Mehr ist da nicht dran.

<div class="svginside" style="max-width:400px">
   <canvas height="629" width="500"></canvas>
   <svg width="100%" height="100%" viewBox="0 0 500 629">
      <image id="pixl" height="629" width="1500" y="0" x="0" xlink:href="fraisier1500-629.jpg"/>
   </svg>
</div>
<div class="svginside" style="max-width:400px;">
   <canvas height="629" width="500"></canvas>
   <svg width="100%" height="100%" viewBox="0 0 500 629">
      <use xlink:href="#pixl" transform="translate(-500)"/>
   </svg>
</div>
<div class="svginside" style="max-width:400px;">
   <canvas height="629" width="500"></canvas>
   <svg width="100%" height="100%" viewBox="0 0 500 629">
      <use xlink:href="#pixl" transform="translate(-1000)"/>
   </svg>
</div>

Statt das Seitenverhältnis der Image-Sprites aus Breiten und Höhen zu berechnen, darf abgeschrieben werden: Breite und Höhe des SVG-Elements aus der viewBox in das canvas-Element übernehmen.

Während die div class=“sprites“-Elemente leer sind, können die SVG-Elemente durch title und desc-Tags beschrieben werden.

2019-11-16 SITEMAP BLOG