Hoe maak je responsive afbeeldingen in Plate?

Met de nieuwe feature voor afbeeldingen (image preprocessing), zijn de toepassingen van responsive afbeeldingen ook verbeterd. In deze blog ga ik in op welke mogelijkheden je als sitebouwer hebt voor responsive afbeeldingen.

Goede responsive afbeeldingen bestaan nog steeds uit de standaard <img> tag, maar hebben de extra html-attributen srcset en sizes. srcset heeft een set met afbeeldingen, waaruit de browser de meest geschikte kiest aan de hand van de schermgrootte, met behulp van het sizes attribuut. De browser let echter ook op de pixeldichtheid (dpi). De dpi op veel smartphones is namelijk heel hoog, maar ook bijvoorbeeld op Apple retina schermen, waardoor scherpe afbeeldingen tonen op dergelijke apparaten een uitdaging kan zijn. Responsive afbeeldingen zijn daarbij een uitkomst. Als je meer wilt lezen over hoe responsive afbeeldingen precies werken, raad ik je een artikel van Eric Portis aan.

Maar hoe maken we responsive afbeeldingen in Plate? We gaan er in dit artikel vanuit dat we een website hebben met 4 viewports (de standaard in Plate), waarvan de breekpunten als volgt zijn:

xs: <= 767px
sm: <= 991px
md: <= 1199px
lg: >= 1200px

Als we een afbeelding binnen de rijen/kolommen structuur van Plate aanroepen, kunnen we gebruik maken van het avg_image_width attribuut voor een kolom, wat de gemiddelde breedte van een afbeelding teruggeeft voor de kolom, per viewport (docs).

Dit doen we als volgt:

{%- for viewport in site.viewports -%}
  {%- assign img_width = column.viewport_options[viewport.name].avg_image_width -%}
{%- endfor -%}

Met deze code bepalen we de breedte van de afbeelding, die we uit de avg_image_width van de kolom halen. Vervolgens vullen we een array met een passende grootte van de afbeelding voor elke viewport:

{%- assign srcset = image.image | img_url: img_width | append: " " | append: img_width | append: "w" -%}
{%- assign srcsets = srcsets | push: srcset -%}

Zoals je ziet wordt er nog iets achter de url geplakt: de breedte van de afbeelding, aangevuld met een ‘w’. Dit is benodigd om van de srcset een valide html-attribuut te maken. Zie ook het artikel over responsive afbeeldingen voor meer info over hoe dit werkt. Voor het sizes attribuut doen we ongeveer hetzelfde:

{%- assign size = img_width | append: "px" -%}
{%- if viewport.min_width > 0 -%}
  {%- assign size = "(min-width:" | append: viewport.min_width | append: "px) " | append: size -%}
{%- endif -%}
{%- assign sizes = sizes | push: size -%}

Hiermee maken we ook een array met alle elementen voor het sizes attribuut. Elke size bestaat uit de breedte van de afbeelding aangeduid in pixels. Voor alle viewports behalve de kleinste wordt er ook nog een mediaquery-achtige string achter geplaatst, om aan te geven voor welke viewport de size geldt.

Vervolgens worden alle arrays samengevoegd tot een string, wat de uiteindelijke html-attributen worden:

{%- assign src = srcsets[0] | split: " " | first -%}
{%- assign srcsets = srcsets | join: "," -%}
{%- assign sizes = sizes | reverse | join: ", " -%}

De ‘gewone’ src wordt ook nog gemaakt, als fallback. De aangemaakte variabelen worden als html-attributen in een img_tag gestopt:

{{ src | img_tag: srcset: srcsets, sizes: sizes }}

De complete code ziet er als volgt uit:

{%- for viewport in site.viewports -%}
  {%- assign img_width = column.viewport_options[viewport.name].avg_image_width -%}

  {%- assign srcset = image.image | img_url: img_width | append: " " | append: img_width | append: "w" -%}
  {%- assign srcsets = srcsets | push: srcset -%}

  {%- assign size = img_width | append: "px" -%}
  {%- if viewport.min_width > 0 -%}
    {%- assign size = "(min-width:" | append: viewport.min_width | append: "px) " | append: size -%}
  {%- endif -%}
  {%- assign sizes = sizes | push: size -%}
{%- endfor -%}

{%- assign src = srcsets[0] | split: " " | first -%}
{%- assign srcsets = srcsets | join: "," -%}
{%- assign sizes = sizes | reverse | join: ", " -%}

{{ src | img_tag: srcset: srcsets, sizes: sizes }}

Zo maken we dus responsive afbeeldingen: voor elke viewport een juiste grootte, waarvan vervolgens een valide <img> html-tag gemaakt wordt. Het resultaat is als volgt:

<img src="./img-url-1.jpg" 
  srcset="./img-url-1.jpg 360w, ./img-url-2.jpg 290w, ./img-url-3.jpg 383w, ./img-url-4.jpg 470w" 
  sizes="(min-width:1200px) 470px, (min-width:992px) 383px, (min-width:768px) 290px, 360px">

Als je meer wilt weten, stel dan gerust je vraag in de Plate Partner Slack. Of lees verder met het artikel van Eric Portis over responsive afbeeldingen of de volledige documentatie van het img_url filter.


1 x per maand tips voor de ontwikkeling van je websites met Plate ontvangen?

Weten wat Plate voor jou kan betekenen?

Blijf op de hoogte van nieuwe updates en features via onze nieuwsbrief