Als Apple vor einigen Jahren anfing, seine iPhones, iPads und MacBooks mit hochauflösenden Displays – den sogenannten Retina-Displays – auszustatten, hat das zu einer deutlichen Verbesserung der Darstellungsqualität geführt. Einzelne Pixel sind auf diesen Displays nicht mehr als solche zu erkennen. Mittlerweile sind hochauflösende Displays längst keine Besonderheit mehr. Vor allem aktuelle Mobilgeräte sind schon in der Mittelklasse hochauflösend. Während viele Apps für Mobilgeräte schon länger auf die hohe Auflösung ausgerichtet sind, lassen sich mittlerweile auch per HTML5, CSS3 und JavaScript hochauflösende Websites realisieren – ohne zusätzliche JavaScript-Bibliotheken.
Doppelt so scharf dank doppelter Pixeldichte
Als Standardbreite für Mobilgeräte haben sich – historisch bedingt – 320 Pixel etabliert. Viele mobile Websites sind auf diese Breite ausgerichtet. Hochauflösende Displays haben doppelt so viele oder noch mehr Pixel. Damit eine Website auf diesen Displays nicht halb so groß erscheint, wird die Seite quasi hochskaliert. Bei Schriften und Vektorgrafiken ist das kein Problen. Bitmap-basierte Formate wie JPEG- und PNG-Dateien sehen hingegen unscharf und pixelig aus.
Da solche Displays immer häufiger werden, wird es natürlich für Webdesigner und -entwickler zunehmend wichtiger, Webprojekte in hochauflösender Qualität bereitzustellen.
HTML5 und die „srcset“-Eigenschaft
Lange wurde darum gerungen, wie man in HTML5 Bilder für hochauflösende Displays bereitstellen kann. Mittlerweile herrscht Gewissheit und das „srcset
“-Attribut hat sich etabliert. Über das Attribut können mehrere Dateiquellen für verschiedene Pixeldichten angegeben werden. Die Pixeldichte wird per Leerzeichen getrennt hinter den Dateiverweis notiert – zum Beispiel „2x
“ für die doppelte Pixeldichte.
<img srcset="bild.jpg, bild@2x.jpg 2x" src="bild.jpg.webp" width="320" height="160" alt="HTML5 & CSS3: mache deine Website fit für hochauflösende Displays" />
Im Beispiel werden per „srcset
“ zwei Dateien angegeben. Die erste Datei wird bei Displays mit einfacher Pixeldichte geladen. Der Wert „1x
“ kann bei einfachen Pixeldichten weggelassen werden. Es folgt eine Datei für Displays mit doppelter Pixeldichte. Als Fallback für ältere Browser sollte man immer auch das bekannte „src
“-Attribut angegeben. Dort sollte dann das „normale“ Bild referenziert werden.
Vergleich zwischen Bild mit doppelter Pixeldichte (oben) und einfacher Pixeldichte (unten) auf einem hochauflösenden Display
Statt die Pixeldichte anzugeben, gibt es auch die Möglichkeit, die physische Breite oder Höhe eines Bildes an die jeweiligen Dateiquellen innerhalb des „srcset
“-Attributes anzuhängen.
<img srcset="bild-320w.jpg 320w, bild-640w.jpg 640w" src="bild-640w.jpg.webp" alt="HTML5 & CSS3: mache deine Website fit für hochauflösende Displays" />
Entscheidet man sich für diese Variante, wird das Bild immer auf die gesamte Browser- beziehungsweise Fensterbreite skaliert – vorausgesetzt, es werden keine „height
“- und „width
“-Attribute gesetzt.Der Browser wählt dann jeweils die Datei aus, die für die Darstellung benötigt wird. Wird das Bild im Beispiel in einer Breite von bis zu 320 Pixel dargestellt, wird die Datei „bild-320w.jpg
“ genommen. Bei Auflösungen darüber wird die Datei „bild-640w.jpg
“ verwendet.
Über das „sizes
“-Attribut hat man nun noch die Möglichkeit, die darzustellende Breite des Bildes zu beeinflussen. Dazu werden Media-Angaben in Kombination mit der gewünschten Darstellungsbreite des Bildes angegeben.
<img srcset="bild-320w.jpg 320w, bild-640w.jpg 640w" sizes="(min-width: 320px) 50vw, (max-width: 320px) 100vw" src="bild-640w.jpg.webp" alt="" />
Im Beispiel wird das Bild bei einer Viewport-Breite von mindestens 320 Pixel („min-width: 320px
“) so skaliert, dass es 50 Prozent der Breite des Viewports („50vw
“) einnimmt. Bei einer Viewport-Breite von weniger als 320 Pixel nimmt das Bild den gesamten Viewport in der Breite ein („100vw
“).
Unterschiedliche Darstellungsbreite: Im Portrait-Modus 100 Prozent und im Landscape-Modus 50 Prozent des Viewports
Innerhalb einer „srcset
“-Dateireferenz kann immer nur die Pixeldichte (zum Beispiel „2x
“) oder Breite und Höhe (zum Beispiel „320w 160h
“) angegeben werden. Eine Kombination von Pixeldichte und Breite beziehungsweise Höhe ist nicht möglich.
Das „srcset
“-Attribut funktioniert auch in Kombination mit dem neuen „<picture>
“- und dem dazugehörigen „<source>
“-Element. Über das „<picture>
“-Element hat man die Möglichkeit, Bilder für verschiedene Display- beziehungsweise Fenstergrößen festzulegen. Auch hier können dann Quellen für unterschiedliche Pixeldichten hinterlegt werden.
<picture> <source srcset="bild-640w.jpg, bild-640w@2x.jpg 2x" media="(min-width: 320px)" /> <source srcset="bild-320w.jpg, bild-320w@2x.jpg 2x" media="(max-width: 320px)" /> <img src="bild-640w.jpg.webp" width="320" height="160" alt="" /></picture>
Im Beispiel werden über die beiden „<source>
“-Elemente insgesamt vier Dateiquellen referenziert. Display- beziehungsweise Fensterbreiten bis 320 Pixel stellen die Dateien „bild-320w.jpg
“ und „bild-320w@2x.jpg
“ (je nach Pixeldichte) dar. Bei größeren Breiten werden die Dateien „bild-640w.jpg
“ und „bild-640w@2x.jpg
“ aufgerufen. Berücksichtigen muss man, dass das „<source>
“-Element keine „width
“- und „height
“-Attribute kennt. Will man die Größenangaben festlegen, muss man dies per CSS machen.
Auch hierbei sollte man wieder ein „<img>
“-Fallback bereitstellen, um ältere Browser nicht außen vor zu lassen.
Das „srcset
“- und „sizes
“-Attribut sowie das „<picture>
“-Element werden von Chrome und Firefox jeweils ab Version 38 unterstützt. Der Internet Explorer unterstützt die Attribute und das Element derzeit noch nicht. Android-Chrome ist ab Version 40, iOS-Safari ab Version 8.1 dabei. Letzterer unterstützt „sizes
“ aber nur eingeschränkt.
Wer das „srcset
“-Attribut auch für Browser verwenden möchten, die es noch nicht unterstützen, kann sich mit einem Polyfill behelfen, welches die Funktionalität für ältere Browser nachbildet.
CSS3 und „image-set()“
Auch per CSS3 gibt es mittlerweile eine Möglichkeit, unterschiedliche Bildquellen für verschiedene Pixeldichten anzugeben. Hierfür steht die „image-set()
“-Notation zur Verfügung. In dieser lassen sich ähnlich wie beim HTML5-Attribut „srcset
“ mehrere Dateien per „url()
“ referenzieren. Die Notation „image-set()
“ kann überall dort eingesetzt werden, wo eine Bildquelle per „url()
“ angegeben wird.
body { background-image: url("hg.jpg"); background-image: image-set( url("hg.jpg") 1x, url("hg@2x.jpg") 2x );}
Im Beispiel wird per „image-set()
“ eine Hintergrundgrafik für zwei Pixeldichten definiert. Derzeit sollte man die Notation mit entsprechenden Vendor-Präfixen auszeichnen – zum Beispiel „-webkit-image-set()
“. Außerdem ist es auch hier ratsam, für ein Fallback zu sorgen. Wichtig ist, dass das Fallback wie im Beispiel vor der „image-set()
“-Variante notiert wird. Browser, die „image-set()
“ nicht kennen, werden die zweite „background-image
“-Eigenschaft ignorieren. Alle anderen Browser werden die zweite Eigenschaft ausführen und somit die erste damit überschreiben.
Hochauflösender Hintergrund (oben) und normal aufgelöster Hintergrund (unten)
Die „image-set()
“-Notation wird derzeit vom Chrome ab Version 31 unterstützt. Firefox und Internet Explorer unterstützen sie nicht. Außerdem kennen der iOS-Safari ab Version 7.1 und der Android-Chrome ab Version 40 diese Notation.
Neben der „image-set()
“-Notation, welche unterschiedliche Pixeldichte nur bei Bildern berücksichtigt, gibt es auch noch die Media-Query-Angaben „min-resolution
“ und „max-resolution
“. Hier können beliebige CSS-Eigenschaften für verschiedene Pixeldichten berücksichtigt werden.
@media screen and (min-resolution: 2dppx) { body { background: url("hg@2x.jpg"); }}
Im Beispiel wird per „min-resolution
“ eine Hintergrundgrafik für Displays mit doppelter Pixeldichte definiert. Die Einheit „dppx
“ steht für „dot per pixel
“ und somit für die Pixeldichte. Es stehen aber auch andere Einheiten zur Verfügung. So kann man beispielsweise „dpi
“ für „dots per inch
“ verwenden. Damit ist es beispielsweise möglich, Bilder in Druckauflösung bereitzustellen. Als letzte Einheit gibt es noch „dpcm
“, was für „dots per centimeter
“ steht. Für die Darstellung auf Monitoren sollte man die Einheit „dppx
“ verwenden.
Das „resolution
“-Feature wird von Chrome ab Version 31 und Firefox ab Version 35 unterstützt. Der Internet Explorer unterstützt das Feature ab Version 9, aber nur mit der Einheit „dpi
“. Android-Chrome kennt das Feature seit Version 40 und iOS-Safari ab Version 7.1 – allerdings nur in der veralteten Schreibweise „min-device-pixel-ratio
“ beziehungsweise „max-device-pixel-ratio
“.
Alternative: Bitmaps grundsätzlich in hoher Auflösung bereitstellen
Die neuen HTML5-Elemente und -Attribute ermöglichen es zwar, Bilder für verschiedene Auflösungen und Pixeldichten bereitzustellen. Allerdings müssen meist mehrere unterschiedliche Dateien für ein Bild generiert werden. Content-Management-Systeme wie TYPO3 automatisieren dies zwar. Aber bei handgemachten Webprojekten, die ohne serverseitige Programmiersprache auskommen müssen, steht man vor der Aufgabe, all diese Dateivarianten manuell zu generieren.
Wer diesen Aufwand scheut, aber dennoch auch hohe Pixeldichten berücksichtigen möchte, kann einen Zwischenweg gehen, bei dem man mit jeweils einer Datei für alle Pixeldichten auskommt. Dazu wird die Bilddatei direkt in doppelter Auflösung erstellt – am Besten in reduzierter Qualität –, dann aber mit halber Auflösung in ein HTML-Dokument eingebunden. Ein Bild mit 640 mal 320 Pixel Größe würde dann also in dieser Weise verwendet.
<img src="bild-640w.jpg.webp" width="320" height="160" alt="" />
Während hochauflösende Displays die volle physische Auflösung darstellen, wird auf „normalen“ Displays das Bild auf die Hälfte der Größe herunter skaliert. Bei normaler Pixeldichte wird die schlechte Qualität durch die verkleinerte Darstellung wett gemacht. Bei doppelter Pixeldichte hat man immer noch eine bessere Qualität als bei der Verwendung eines Bildes in normaler Auflösung.
Der Nachteil dieser Herangehensweise ist natürlich, dass bei Displays mit einfacher Pixeldichte eine unnötig große Datei heruntergeladen wird. Daher bietet es sich an, diese Möglichkeit nur mit etwas stärker komprimierten JPEG-Dateien einzusetzen.
Stark komprimierte JPEG-Datei in halber Auflösung (oben)
Auch per CSS können Bilder in doppelter Auflösung eingebunden werden. Mit der Eigenschaft „background-size
“ hat man hierbei die Möglichkeit, das Bild auf die Hälfte der Auflösung herunter zu skalieren.
body { background-image: url("hg.jpg"); background-size: 32px 16px;
Hat das Hintergrundbild im Beispiel eine Auflösung von 64 mal 32 Pixel, wird es um 50 Prozent verkleinert dargestellt. Man erreicht somit denselben Effekt wie beim HTML-Beispiel.
SVG-Grafiken und Iconfonts verwenden
Alle aktuellen Browser unterstützen mittlerweile das vektorbasierte SVG-Format. Vor allem Logos und viele andere grafischen Elemente sind ja meist als Vektorgrafiken vorhanden und wurden bislang als GIF- oder PNG-Datei in eine Website eingebunden. Dank des SVG-Formates können diese auch direkt als Vektorgrafik in einer Website dargestellt werden – sei es per HTML über das „<img>
“-Element oder per CSS über „url()
“.
Der Vorteil des SVG-Formates liegt auf der Hand: Da es vektorbasiert ist, wird es stets in bester Auflösung dargestellt. Zudem schont es die Bandbreite und spart Arbeit, da es nicht für die verschiedenen Auflösungen und Pixeldichten bereitgestellt werden muss.
Alternativ zu SVG-Grafiken sind Iconfonts bestens für hochauflösende Displays geeignet. Schließlich sind ebenso Schriften vektorbasiert und werden daher immer in optimaler Auflösung dargestellt.
Wer bei SVG-Grafiken auf Nummer sicher gehen und ältere Browser ohne SVG-Unterstützung berücksichtigen will, kann mit einigen Kniffen hierfür Fallback-Lösungen einbauen.
Pixeldichte mit JavaScript feststellen
Gelegentlich werden Bilder per JavaScript geladen – zum Beispiel bei Galerien. Statt ein „<img>
“-Element mit allen „srcset
“-Referenzen per JavaScript zu generieren, kann auch direkt die richtige Bildquelle in der für das Gerät zutreffenden Pixeldichte geladen werden.
Denn JavaScript kennt die Eigenschaft „devicePixelRatio
“, mit der die Pixeldichte abgefragt werden kann.
if (window.devicePixelRatio > 1) { document.getElementsByTagName("img")[0].src = "bild@2x.jpg";}
Im Beispiel wird eine Bilddatei geladen, wenn die Pixeldichte größer 1 ist. Logischerweise kann die Eigenschaft nur ausgelesen werden.
Eine Sache sollte man bei der Verwendung von „devicePixelRatio
“ beachten. Denn der durch diese Eigenschaft ermittelte Wert ist immer abhängig vom jeweiligen Zoomfaktor des Browsers. Wird ein Dokument per Browserzoom in einer Größe von 150 Prozent dargestellt, liefert „devicePixelRatio
“ einen Wert von „1.5
“ – bei einfacher Pixeldichte. Bei doppelter Pixeldichte würde bei diesem Zoomfaktor der Wert „3
“ zurückgegeben werden.
Fazit und Links zum Beitrag
Webprojekte für hochauflösende Displays fit zu machen, kann eine recht umfangreiche Aufgabe sein. Allerdings sollte man – gerade bei neuen Projekten – hohe Pixeldichten immer berücksichtigen. Alle vorgestellten Lösungen können relativ einfach mit Fallbacks ausgestattet werden, sodass man nie Gefahr läuft, ältere Browser außen vor zu lassen.
(Der Artikel erschien erstmalig am 16. März 2015 und wurde von dem Autor vor seiner erneuten Veröffentlichung auf seine Aktualität hin geprüft.)
(dpe, DO)
Eine Antwort
Halli, hallo,
nach dem Lesen dieses Artikels bin ich zwar deutlich schlauer geworden. Danke dafür aber es stellen sich bei mir einige Fragen:
– Die Navigation mit HTML 5: wie soll sie aussehen, ich weiss, dass man die Navi aus SEO-Sicht am besten als Liste darstellen sollte. Wie sollte sie aber in HTML 5 aussehen
– Bilder: Aus SEO-Sicht sollte man sich das Skalieren von Bilder mit HTML lieber sparen und die benötigten Bilder im passenden Format auf dem Server haben. Wie ist das den in HTML 5, da gibt es sowas wie „sizes“-Attribut. Ist das das gleiche wei Skalieren?
– Wie schnell sollte man auf HTML 5 umstellen und welche Auswirkung hat es auf SEO. wurde es mal irgendwie gemessen?
Gruß