img srcset und sizes – Alternative Bildgrößen

img srcset und sizes: Responsive Bilder mit Auflösung und Seitenverhältnis (aspect ratio)

Die Attribute srcset und sizes des img-Tags sind der Schlüssel zu responsiven Bildern. srcset listet alternative Bildgrößen als Set von Bildern, unter denen der Browser ein Bild aussuchen kann. sizes setzt die Bedingungen, zu denen der Browser das Bild aussucht, z.B. nach Größe und Ausrichtung des ViewPorts.

scrset

srcset ist eine Liste von unterschiedlich hoch auflösenden Versionen eines Bildes und ihrer Größe. Wird das Bild im Porträt-Modus des Handys geladen, lädt der Browser die höhere Auflösung im Landscape-Modus nicht nach, wenn das Handy gedreht wird. Dasselbe gilt für das Aufziehen und Verkleinern des Browserfensters: Die zuerst geladene Version bleibt.

Für Browser, die srcset nicht unterstützen (IE11 und älter), ist das altgediente src-Attribut ausschlaggebend.

HTML img srcset – Bilder je nach Breite des Viewports laden
<img 
src="needles-1440.jpg"
        //    url        size
srcset="needles-780.jpg  780w,   // Viewport bis zu 780
        needles-1024.jpg 1024w,  // Viewport größer als 780
        needles-1440.jpg 1440w,  // Viewport größer als 1024
        needles-2400.jpg 2400w"  // Viewport größer als 1440
width="780" height="521" alt="Bilder je nach Breite des Viewports">

Der einfache Ansatz mit srcset lädt die Bilder je nach Breite des Viewports und lässt die Anzeigegröße des Bildes außer Acht. Wenn das Bild nicht gerade zur fensterfüllenden Slideshow gehört, liefert diese Variante zu große Bilddateien aus.

Selbst auf einem großen Monitor mit einer Auflösung von 2048 x 1152 oder mehr hat das Bild im Layout höchstens eine Breite von 880px. Ganz davon abgesehen gibt der Validator dieser Konstruktion auch keinen Segen: Wo Bilder mit srcset angeboten werden, muss sizes das Platzangebot mitteilen.

Für die passgenaue Auslieferung der Bilddatei kommt also das Attribut sizes ins Spiel. sizes listet Bedingungen, ähnlich wie Media Queries.

srcset und sizes

sizes ist die Vorgabe, in welcher Situation welche Bildgröße eingesetzt wird. Das passiert anhand einer Media Query und jeweiligen Breite des Bildes. Wenn die Seite auf einem großen Monitor eine Sidebar setzt, muss das Bild nicht mehr für die volle Breite des Viewports reichen, sondern nur für die jeweilige Breite des umfassenden Blocks.

Einsatz von srcset und sizes je nach verfügbarem Platz
<div class="container">
   <img src="https://www.mediaevent.de/xhtml/img/needles-1440.jpg" 
       srcset="https://www.mediaevent.de/xhtml/img/needles-780.jpg 780w,
               https://www.mediaevent.de/xhtml/img/needles-1024.jpg 1024w,
               https://www.mediaevent.de/xhtml/img/needles-1440.jpg 1440w,
               https://www.mediaevent.de/xhtml/img/needles-2400.jpg 2400w"

       sizes = "(min-width: 1600px) 1200px, // ViewPort mindestens 1600 px, nimm Bild mit 1200px Breite
               (min-width: 1400px) 1100px,  // ViewPort mindestens 1400 px, nimm Bild mit 1100px Breite
               (min-width:1000px) 900px,    // ViewPort mindestens 1000 px, nimm Bild mit 900px Breite
               100vw"                       // kleinerer ViewPort: volle Breite des ViewPorts (100vw)

       width="780" height="521" 
       alt="HTML img srcset – Bilder je nach Breite des Viewports laden">
</div>

Wir haben also weiterhin in srcset die Liste mit den verschiedenen Auflösungen des Bildes.

Die Media Querys verlangen nach Bildern, für die keine entsprechende Bildauflösung vorhanden ist. Kein Problem – das überlassen wir dem Browser, der die beste Bildgröße aus den verfügbaren Vorgaben wählt. Das macht die Kombination aus srcset und sizes so flexibel.

Auf dem Handy zeigt der Browser die Bildversion jetzt mit 780px, das Tablett bekommt die volle Ladung von 2400px? Auch wenn Handy und Tablet hochkant nach außen 320px bzw 768px Breite zeigen, ist ihre physikalische Auflösung deutlich höher: Sie haben Retina-Monitore.

Auflösung

Die Auflösung ist das Maß für die Schärfe und Farbbrillanz des Bildes und ist ein Merkmal von Monitoren und als auch von Bildern (und auch der Drucker hat eine Auflösung).

Hoch auflösende Bilder mit ihren langen Ladezeiten sind ein Handycap für responsive Webseiten auf mobilen Geräten. Auf der einen Seite wollen wir eine hohe Qualität für große Monitore und Retina-Displays, auf der anderen Seite wollen wir Mobiltelefone und Tabletts nicht mit den großen Bildern erschlagen: Bandbreite bleibt kostbar.

<img src="img1.png"  
     srcset="img2.png 100w, img3.png 500w, img4.png 1000w"

     sizes="(Media-Bedingung) Breite,
            (Media-Bedingung) Breite,
            optional Default-Breite">

Eine Media-Bedingung ähnelt einer Media Query, ist aber nicht ganz dasselbe, sondern nur ein Teil einer Media Query.

Bedingungen können wie folgt aussehen:

  • Einfache Bedingung (min-width: 900px)
  • nicht-Bedingung ( not (orientation: landscape) )
  • und-Bedingung (orientation: landscape) and (min-width: 900px)
  • oder-Bedingung ( (orientation: portrait) or (max-width: 500px) )

Die Breite kann in em, rem, px oder als Viewport-Breite (w) geschrieben werden (nicht aber in %). In voller Schönheit kann ein img-Element dann so aussehen:

<img src="img1.png"  
     srcset="img2.png 100w, img3.png 500w, img4.png 1000w"

     sizes="(min-width: 900px) 1000px,
            (max-width: 900px) and (min-width: 400px) 50em,
            ( not (orientation: portrait) ) 300px,
            ( (orientation: landscape) or (min-width: 1000px) ) 50vw, 
            100vw">

Mit der ersten zutreffenden Bedingung pickt sich der Browser die am besten passende Bildgröße aus dem Set des srcset-Attributs.

Die Auflösung der Retina-Monitore

Die Auflösung des Monitors (PPI – Pixel pro Inch) wird in Pixeln für die Breite und die Höhe angegeben. Herkömmliche Desktop-Monitore stellen ein Bild i.d.R. mit 72, 96 oder 120 Pixeln pro Inch dar. Retina-Displays erreichen extreme Auflösungen von rund 300 bis 400 Pixeln pro Inch. So kommt es, dass große Monitore eine kleine Auflösung, kleine Monitore eine hohe Auflösung haben können.

Bei Fotos ist mit Auflösung die Zahl der Pixel in der Breite und Höhe gemeint. Zusätzlich haben Fotos auch eine Druck-Auflösung (meist 300 DPI – Dots per Inch), die aber für den Monitor irrelevant ist.

Monitor niedrige Auflösung vs hohe Auflösung (monitor resolution)

Retina-Monitore setzen einen Pixel durch vier oder mehr Pixel um und erzielen schärfere Bilder und brillantere Farben. Bilder mit einer speziellen Vorgabe im srcset-Attribut des img-Tags nutzen die volle Leistung der Retina-Monitore.

<img alt="medium" srcset="medium.jpg 1x, large.jpg 2x">
HTML img srcset Beispiel

Der Browser nimmt was passt

Hier stehen also zwei Bildgrößen zur Verfügung, die je nach Auflösung des Monitors geladen und angezeigt werden. Der Browser entdeckt die Auflösung / Pixeldichte des Monitors und entscheidet, welches Bild er einsetzt.

1x bzw. 2x steht für Device Pixel Ratio – das Verhältnis [Anzahl der Pixel in der Breite] zu [Breite in Zoll].

  • 1x steht für herkömmliche Monitore, die mit 72 bis 100 Pixeln pro Zoll auflösen,
  • 2x steht für hochauflösende Monitore, die mit 200 Pixeln und höher pro Zoll auflösen – sogen. »Retina«-Monitore.

Es gibt auch Displays, deren Pixeldichte zwischen 1x und 2x liegen. Also wäre auch ein device-pixel-ratio von 1.5x eine denkbare Media Query auf die Auflösung des Monitors.

DevicePixel per Inch (PPI)Bildschirmauflösung (Pixel pro Zoll)
iPhone 6,7,8 Plus (6s,7s,8s Plus)4011920 × 1080
iPad Pro (12,9″)2642732 × 2048
MacBook Pro – Retina Display (15")2202880 × 1800

Der Browser wird das 2x-Bild automatisch um den Faktor 2 verkleinert anzeigen, damit es denselben Raum ausfüllt wie das das Bild mit der 1x-Auflösung. Dieses Verhalten ähnelt der Angabe der DPI bei Bildern für den Druck. Der Zeitschriften- und Buchdruck arbeitet i.d.R. mit 300 dpi, während Bilder auf dem Monitor mit 72 - 120 dpi angezeigt werden.

Browser-Support für srcset

Alle modernen Browser außer IE bis einschließlich IE11 (diese Seite benutzt Picturefill-Polyfill für Browser ohne Support für srcset und picture-Element).

Monitor-Auflösung und Pixel-Auflösung

Allerdings: Die Angabe der Bildschirmauflösung als Kriterium führt dazu, dass nicht nur auf großen Retina-Monitoren wie dem MacBook Pro mit Retina Display, sondern auch auf kleinen Monitoren – z.B. Handy – die 2x-Auflösung angezeigt wird. Hier ist also eine weitere Differenzierung nötig.

Das Bild mit der zweifachen Auflösung soll nur geladen werden, wenn der Platz im Layout verfügbar ist.

Die Kondition für den Einsatz verschiedener Bildgrößen drei Parameter einbeziehen:

  1. Bildgröße relativ zum Viewport (z.B. 33.3vw )
  2. Breite des Viewports z.B. 640px oder 40em
  3. Auflösung des Monitors 1x oder 2x

Was jetzt noch fehlt ist eine Mitteilung an den Browser, wie groß das Bild im Layout dargestellt werden soll – dafür gibt es das Attribut sizes.

srcset = [media query] [length], [media query] [length], …

sizes = "(min-width: 42.5em) 50vw,100vw"

sizes legt den Raum fest, den das Bild innerhalb des Layouts einnimmt. Dann enthält srcset eine Liste der Bilder und ihrer jeweiligen Größe. Mit diesen Informationen wählt der Browser das kleinste Bild, das in das Layout passt und es ausfüllt.

Mit sizes und srcset bestimmt also nicht mehr die Größe des Viewports allein über die Wahl des Bildes.

srcset und sizes
                             1                          2              3
                             +                          +              +
                             |                          |              |
                             v                          v              v
<img sizes="(max-width:720px) 100vw, (max-width: 1260px) 70vw, calc(50vw - 100px)"

   srcset="picture-flowers-320.jpg 320w,  
          /xhtml/img/picture-flowers-640.jpg 640w, 
          /xhtml/img/picture-flowers-720.jpg 720w, 
          /xhtml/img/picture-flowers-960.jpg 960w, 
          /xhtml/img/picture-flowers-1120.jpg 1600w"
   src="/xhtml/img/picture-flowers-640.jpg"

   alt="HTML img: srcset und sizes">
  1. (max-width:720px) 100vw – bis zu einer Breite des Viewports von 720px wird das Bild in voller Breite angezeigt
  2. (max-width: 1260px) 70vw – bei einer Breite des Viewports bis zu 1260px tritt ein Spaltenlayout in Kraft und das Bild liegt in einer Spalte von 70% der Breite des Viewports.
  3. calc(50vw - 100px) – bei noch größeren Viewports liegt das Bild in einer Spalte von 50% der Viewport-Breite (minus 100px Abstand zwischen den Spalten)

Natürlich müssen nicht immer so viele Bildgrößen wie in diesem Beispiel angelegt werden – dahinter sollte auch die Frage stehen, wie groß die Ersparnis zwischen den einzelnen Stufen tatsächlich ist. Hier haben wir nur eine Demo.

sizes und srcset für Spalten Layout (columns)

Wenn anstelle eines Bildes mit gleichem Ausschnitt und gleichen Seitenverhältnissen Bilder mit unterschiedlichen Ausschnitten oder in unterschiedlichen Formaten gezeigt werden sollen – z.B. ein quadratischer Ausschnitt für Handys im Hochformat –, dann ist ein HTML picture-Element u.U. die bessere Wahl als img mit sizes und srcset.