Bilder werden im Webseiten-Framework Hugo per Markdown
definiert. Die Default-Ausspielung generiert ein einfaches Img
-Tag mit dem hinterlegten Bild.
Für dieses Blog habe ich ein Template entwickelt, welches verschiedene Bildauflösungen
für verschiedene Geräte-Auflösungen generiert (responsive images).
Responsive Bilder #
Responsive Images sind Bilder, die sich an die Auflösung des Gerätes anpassen. Die einfachste Implementierung
ist das HTML-Picture
-Element, das eine Liste von Bildern für verschiedene Auflösungen
bereitstellt. Der Browser wählt dann das passende Bild aus.
Das sieht üblicherweise wie folgt aus:
<picture>
<source media="(min-width: 450px)" srcset="img_500.jpg" />
<source media="(min-width: 650px)" srcset="img_700.jpg" />
<img src="img_100.jpg" />
</picture>
Über die Source
-Elemente werden die verschiedenen Auflösungen aufgelistet und
über Media-Queries, wie (min-width: 450px)
, wird die Auflösung des Gerätes abgefragt und das passende Bild ausgewählt.
Das 500-Pixel breite Bild benötigt eine Auflösung von mindestens 450 Pixeln, damit es nicht
aus dem Sichtbereich des Gerätes herausragt.
Das Img
-Tag wird als Fallback verwendet, wenn der Browser kein Picture
-Element unterstützt oder
die Auflösung kleiner ist als das kleinste Source-Element.
Hugo #
In Hugo werden Bilder über Markdown definiert. Das sieht wie folgt aus:
![Bildbeschreibung](/images/bild.jpg)
Die Default-Ausspielung von Hugo generiert ein Img
-Tag:
<img src="/images/bild.jpg" alt="Bildbeschreibung" title="Bildbeschreibung">
Glücklicherweise kann man die Ausspielung des Bildes über ein Template steuern. Das Template
muss hierzu als layouts/_default/_markup/render-image.html
abgelegt werden.
Bilder können in Hugo an zwei Stellen abgelegt werden: Als Page-Resources oder als Static-Resources.
Bei Page-Resourcen wird pro Post / Page ein Ordner unter posts
angelegt und dort können die Bilder
zusammen mit einer index.md
abgelegt werden. Die Bilder werden dann über den relativen Pfad
images/bild.jpg
referenziert. Ich setze dieses Schema nicht ein.
Statische Resourcen liegen normalerweise unter static/images
und werden analog über
images/bild.jpg
referenziert.
Für unsere Zwecke müssen wir die Bilder aber unter assets/images
ablegen, da wir so aus Hugo heraus beliebige Auflösungen generieren können.
Fallbacks, Resourcenauswahl und Bildgrößen #
Damit beide Arten von Bildern unterstützt werden, muss das Template die Bilder anhand des relativen Pfades
suchen. Hierzu wird das Bild zuerst als Page-Resource über .Page.Resources.Get
geladen.
Wenn das Bild nicht gefunden wird, wird es über die statischen Resourcen via resources.Get
geladen.
Für den Fall, dass das Bild nicht gefunden wird, wird im Voraus ein statisches Fallback-Bild definiert.
Dem Template selbst wird das aktuelle Bild-Objekt übergeben.
{{ $originalImage := resources.Get "images/glider.png" }}
{{ with .Destination }}
{{ with $.Page.Resources.Get . }}
{{ $originalImage = . }}
{{ else }}
{{ with resources.Get . }}
{{ $originalImage = . }}
{{ end }}
{{ end }}
{{ end }}
Anschließend wird ermittelt, welche Größe das Originalbild hat. Denn alle größeren Formate sollten wir nicht generieren, das sieht nicht gut aus.
Template #
<!-- Fallback-Bild definieren, dass dann auch klein ist -->
{{ $originalImage := resources.Get "images/glider.png" }}
{{ $myTitle := i18n "image not found" }}
{{ with .Destination }}
{{ $myTitle := $.Title }}
<!-- Page-Resources -->
{{ with $.Page.Resources.Get . }}
{{ $originalImage = . }}
{{ else }}
<!-- Static-Resources -->
{{ with resources.Get . }}
{{ $originalImage = . }}
{{ end }}
{{ end }}
{{ end }}
<p class="md-image">
<picture>
<!-- Größen anhand der Originalgröße bestimmen -->
{{ $width := $originalImage.Width }}
{{ if gt $width 800 }}
{{ with $originalImage.Resize "800x" }}
<source media="(min-width:800px)" srcset="{{ .RelPermalink | safeURL }}" />
{{ end}}
{{ end }}
{{ if gt $width 1200 }}
{{ with $originalImage.Resize "1200x" }}
<source media="(min-width:1200px)" srcset="{{ .RelPermalink | safeURL }}" />
{{ end}}
{{ end }}
{{ if gt $width 1500 }}
{{ with $originalImage.Resize "1500x" }}
<source media="(min-width:1500px)" srcset="{{ .RelPermalink | safeURL }}" />
{{ end}}
{{ end }}
{{ if gt $width 2200 }}
{{ with $originalImage.Resize "2200x" }}
<source media="(min-width:2200px)" srcset="{{ .RelPermalink | safeURL }}" />
{{ end}}
{{ end }}
{{ $tinyImage := $originalImage }}
{{ if gt $width 500 }}
{{ $tinyImage = $originalImage.Resize "500x" }}
{{ end }}
<img src="{{ $tinyImage.RelPermalink | safeURL }}" alt="{{ $myTitle }}" title="{{ $myTitle }}" />
</picture>
</p>
Referenzen & weiterführende Links #
- Artikel “Responsive Images - A Reference Guide from A to Z” von imagekit.io über die Grundlagen von responsiven Bildern
- Artikel “Sizing Images for Responsive Pages” von Edward Wf Chew über empfohlene Bildgrößen bei verschiedenen Auflösungen und Layouts
- Eine Lösung als Hugo-Modul von Utkarsh Verma auf Git
- Webseiten-Framework Hugo
- Markdown