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. CSS Image Sprites und SVG Image Sprites sind die Platzanweiser für die Einzelbilder.

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 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.

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.