Inspiratie
21 min leestijd

Responsive Pic in WordPress

Toine Kamps

Developer

Als digitaal ontwerpbureau gebruiken we al tien jaar WordPress als ons gekozen CMS. Hoewel we nog steeds geloven dat het het meest veelzijdige systeem is voor onze klanten, ontbreekt er één functie in de codex: hoe responsieve afbeeldingen te verwerken in je thema. Daarom zal ik meer informatie delen over Responsive Pics om een dieper inzicht te geven in responsieve afbeeldingen.

Case 1: Kopafbeelding over de volledige breedte

WordPress wordt standaard geleverd met de volgende standaard afbeeldingsformaten:

1Thumbnail: 150px square
2Medium: maximum width of 300px
3Medium Large: maximum width of 768px
4Large: maximum width of 1024px
5Full: original image size

Bij elke upload van media probeert WordPress deze afbeeldingsformaten voor je aan te maken. Zo kun je deze gebruiken bij het invoegen van media in de WYSIWYG-editor. (het medium grote formaat is hier niet beschikbaar) of door een van de ingebouwde WordPress-functies aan te roepen, zoals wp_get_attachment_image_src.

Voor standaardsjablonen met een brede headerafbeelding (16:9 crop-verhouding) upload je de afbeelding op ware grootte met de juiste verhouding.

1<?php     
2$img_id = get_post_thumbnail_id();    
3$img_full = wp_get_attachment_image_src($img_id, 'full');    
4$img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
5?>
6<img class="my-header" src="<?= $img_full[0]; ?>" alt="<?= $img_alt; ?>" />

Maar omdat het serveren van te grote afbeeldingen op je website een van de zwaarste prestatiestraffen heeft in snelheidstestprogramma's zoals GTmetrix, PageSpeed Insights of Experte Page Speed Test en prestaties steeds belangrijker worden in SEO-ranking, wordt dit beschouwd als een slechte gewoonte.

Daarnaast werkt het uploaden van afbeeldingen met de juiste 16:9-verhouding alleen als je je weg weet in Photoshop.

 
Aangepaste afbeeldingsformaten

Dus waarom geen extra aangepast afbeeldingsformaat toevoegen met de functie add_image_size?

1add_image_size('header', 1280, 720, true);

Nu zal WordPress dit formaat voor je maken en bijsnijden voor elke media upload, zodat je het kunt gebruiken in je sjabloon:

1<?php
2    $img_id = get_post_thumbnail_id();
3    $img_header = wp_get_attachment_image_src($img_id, 'header');
4    $img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
5?>
6<img
7    class="my-header" src="<?= $img_header[0]; ?>"
8    alt="<?= $img_alt; ?>"
9/>

Dit lost het verhoudingsprobleem op en het lost ook gedeeltelijk het prestatieprobleem op, omdat de afbeelding wordt verkleind tot 1280px, maar je website kan mogelijk nog steeds een afbeelding van 1280px breed weergeven aan een bezoeker op een mobiel scherm van slechts 640px breed. Dat is dus een verlies van 200%!

Je kunt dus een extra header toevoegen voor kleinere schermen met dezelfde crop ratio:

1add_image_size('header-mobile', 640, 360, true);

En het als volgt weergeven:

1<?php
2    $img_id = get_post_thumbnail_id();
3    $img_header = wp_get_attachment_image_src($img_id, 'header');
4    $img_header_mobile = wp_get_attachment_image_src($img_id, 'header-mobile');
5    $img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
6?>
7<img
8    class="my-header"
9    srcset="<?= $img_header_mobile[0]; ?> 640w, <?= $img_header[0]; ?> 1280w"
10    sizes="(max-width: 640px) 640px, 1280px"
11    alt="<?= $img_alt; ?>"
12/>
 
Retina-ondersteuning

Maar wat als je een retinaversie van de headerafbeelding wilt weergeven op retinaschermen? Moeten we hiervoor een derde aangepast afbeeldingsformaat toevoegen? Ja, dat moet je:

1add_image_size('header-retina', 2560, 1440, true);

Nu kunnen we de resolutie x-descriptors gebruiken:

1<?php
2    $img_id = get_post_thumbnail_id();
3    $img_header = wp_get_attachment_image_src($img_id, 'header');
4    $img_header_retine = wp_get_attachment_image_src($img_id, 'header-retina');
5    $img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
6?>
7<img
8    class="my-header"
9    srcset="<?= $img_header[0]; ?> 1x, <?= $img_header_retina[0]; ?> 2x"
10    alt="<?= $img_alt; ?>"
11/>

Als je de header-, header-retina- en header-mobiele formaten wilt combineren, moeten we de retina-afbeelding met dubbele breedte definiëren:

1<img
2class="my-header"
3srcset="<?= $img_header_mobile[0]; ?> 640w, <?= $img_header[0]; ?> 1280w, <?= $img_header_retina[0]; ?> 2560w"
4sizes="(max-width: 640px) 640px, 1280px"
5alt="<?= $img_alt; ?>"
6/>
 
Prestaties

Voor kleine persoonlijke websites werkt deze methode prima, maar als je meer inhoud en lay-outs voor je site gaat maken, zal je mediabibliotheek ook snel groeien.

Stel dat je afbeeldingen uploadt met een gemiddelde grootte van 2 Mb en een breedte van 3000px en je hebt 200 media-items in je bibliotheek, dan zal dat resulteren in een extra:

1200 x ((640/3000) * 2) = 85,32 Mb
2200 x ((1280/3000) * 2) = 170,66 Mb
3200 x ((2560/3000) * 2) = 341,33 Mb
4——————————————————————————————————-
5                          597,31 Mb

Misschien heeft je website maar 4 pagina's met de sjabloon die deze afbeeldingsgrootte gebruikt. Boem! 588 afbeeldingen worden gegenereerd zonder ooit te worden gebruikt en bijna 600 Mb schijfruimte wordt in beslag genomen zonder reden. Als je een gedeelde hosting hebt met beperkte schijfruimte, kan dit een probleem worden.

Idealiter wil je alleen een (aangepast) afbeeldingsformaat genereren op de locaties in je lay-out waar dat nodig is, net zoals diensten als Cloudinary bieden.

Dit was een van de redenen waarom we besloten onze eigen tool hiervoor te schrijven: Responsive Pics en deze beschikbaar te stellen als open-source project.

 
Ons doel

Ons doel was om een eenvoudige syntaxis te maken waarmee iedere WordPress template auteur verschillende afbeeldingsformaten zou kunnen genereren, direct in onze templates en alleen voor de afbeeldingen die gebruikt zullen worden in die templates, zodat we responsieve markup kunnen gebruiken zoals het nieuwe <picture> element of de srcset en sizes syntaxis op <img> elementen.

Dus in plaats van te controleren welke voorgedefinieerde formaten voor je afbeelding beschikbaar zijn om te gebruiken in je sjabloon, draai je het om en geef je WordPress de taak om die afbeeldingsgrootte voor je te maken in de sjabloon zelf.

Een andere voorwaarde was dat er geen externe afhankelijkheden moesten zijn voor het maken van afbeeldingen. Hiermee voorkom je dat het te breed toegankelijk zou zijn voor elke gebruiker. Daarom waren we beperkt in het gebruik van WordPress' ingebouwde klasse WP_Image_Editor.

Na intensief testen en finetunen gedurende de afgelopen 2 jaar, hebben we precies het bovenstaande bereikt!

Dus om dat grote header-scenario opnieuw te maken met een uitsnedeverhouding van 16:9 in meerdere formaten en met retina-ondersteuning, kunnen we nu deze one-liner functie gebruiken:

1<?= ResponsivePics::get_image(get_post_thumbnail_id(), 'xs-full', '0.56'); ?>

En dat zal de volgende html-opmaak voor je genereren:

1<img
2    srcset="/app/uploads/2020/11/my-header-1400×784-center-center.jpg 1400w,
3      /app/uploads/2020/11/my-header-1400×784-center-center@2x.jpg 2800w,
4      /app/uploads/2020/11/my-header-1400×784-center-center.jpg 1400w,
5      /app/uploads/2020/11/my-header-1400×784-center-center@2x.jpg 2800w,
6      /app/uploads/2020/11/my-header-1200×672-center-center.jpg 1200w,
7      /app/uploads/2020/11/my-header-1200×672-center-center@2x.jpg 2400w,
8      /app/uploads/2020/11/my-header-992×556-center-center.jpg 992w,
9      /app/uploads/2020/11/my-header-992×556-center-center@2x.jpg 1984w,
10      /app/uploads/2020/11/my-header-768×430-center-center.jpg 768w,
11      /app/uploads/2020/11/my-header-768×430-center-center@2x.jpg 1536w,
12      /app/uploads/2020/11/my-header-576×323-center-center.jpg 576w,
13      /app/uploads/2020/11/my-header-576×323-center-center@2x.jpg 1152w"
14    sizes="(min-width: 1400px) 1400px,
15      (min-width: 1200px) 1400px,
16      (min-width: 992px) 1200px,
17      (min-width: 768px) 992px,
18      (min-width: 576px) 768px,
19      (min-width: 0px) 576px, 100vw"
20    src="/app/uploads/2020/11/my-header.jpg"
21    alt="Responsive header image example"
22>

Dus, wat voor soort tovenarij is dit zou je kunnen denken?
Ik zal het even uitleggen;

 
Responsieve breekpunten

Allereerst is het je waarschijnlijk opgevallen hoeveel afbeeldingen er zijn gedefinieerd in srcset en de media queries die zijn ingesteld in sizes. Om een verscheidenheid aan afbeeldingsformaten te creëren die het beste passen op verschillende schermformaten, gebruikt Responsive Pics de volgende standaard breekpunten die deze media queries definiëren:

1xs: 0
2sm: 576px
3md: 768px
4lg: 992px
5xl: 1200px
6xxl: 1400px

Omdat wij als digitaal bureau en de meerderheid van de ontwikkelaars nog steeds graag CSS-frameworks gebruiken bij het ontwikkelen van frontends, hebben we onze standaardwaarden gebaseerd op de populairste: Bootstrap 4, maar je kunt ook je eigen breekpunten definiëren of toevoegen met de functie setBreakPoints:

1ResponsivePics::setBreakPoints([
2   'xs'    => 0,
3   'sm'    => 576,
4   'md'    => 768,
5   'lg'    => 992,
6   'xl'    => 1200,
7   'xxl'   => 1400,
8   'xxxl'  => 1600,
9   'xxxxl' => 1920
10]);

Met deze onderbrekingspunten op zijn plaats zal onze plugin voor elk onderbrekingspunt met de opgegeven grootte proberen het formaat aan te passen en/of de afbeelding bij te snijden. Je hoeft dit formaat niet voor elk onderbrekingspunt te definiëren als het hetzelfde moet blijven. Wanneer je slechts 1 onderbrekingspunt definieert, zal Responsive Pics hetzelfde formaat gebruiken voor elk volgend onderbrekingspunt naar boven.

In ons minimale voorbeeld is dit:

1<?= ResponsivePics::get_image(get_post_thumbnail_id(), 'xs-full', '0.56'); ?>

wordt eigenlijk geïnterpreteerd als:

1<?= ResponsivePics::get_image(get_post_thumbnail_id(), 'xs-full, sm-full, md-full, lg-full, xl-full, xxl-full', '0.56'); ?>

 

Afbeeldingsgrootte

In ons voorbeeld vragen we dus eigenlijk om een 'volledig' afbeeldingsformaat voor alle onderbrekingspunten. De syntaxis 'volledig' betekent dat we de breedte van het volgende onderbrekingspunt willen gebruiken om het formaat van de afbeelding aan te passen:

10 < 576px: 576px
2576 < 768px: 768px
3768 < 992px: 992px
4992 < 1200px: 1200px
51200 < 1400px: 1400px
6≥ 1400px: 1400px

 

Afbeelding bijsnijden

Omdat de afbeeldingsbronnen in een responsief afbeeldingselement identiek moeten zijn, afgezien van hun grootte (dezelfde beeldverhouding, hetzelfde brandpunt), kunnen we een globale uitsnijdverhouding voor de afbeelding instellen: 0,56 met een standaard uitsnijpositie vanuit het midden.

Dit zal de hoogte van de afbeelding in elk onderbrekingspunt instellen op 56% van de breedte:

10 < 576px:  576px x 322px
2576 < 768px:  768px x 430px
3768 < 992px:  992px x 556px
4992 < 1200px: 1200px x 672px
51200 < 1400px: 1400px x 784px
6≥ 1400px: 1400px x 784px
 
Beelddichtheid

Voor elk gevraagd afbeeldingsformaat in het breekpunt, zal de plugin automatisch proberen het formaat te vermenigvuldigen met 2 voor retina-ondersteuning en het toevoegen aan de beschikbare afbeeldingsbronnen.

 

Prestaties

De uitvoer schaalt de afbeelding alleen omlaag, niet omhoog, en toont altijd de meest geschikte grootte voor het scherm. Dit verbetert direct de snelheid van je pagina's en deze keer zijn er slechts 12 afbeeldingen gegenereerd!

Case 2: Afbeelding op basis van kolommen

Een ander veelvoorkomend gebruik tijdens het templateren is het weergeven van een afbeelding in een op kolommen gebaseerd rastersysteem. Het meest gebruikte rastersysteem is bootstrap, dus we gebruiken opnieuw de standaardinstellingen van Bootstrap 4, dat 12 kolommen, een rand van 30px en container-max-wijdten van gebruikt:

1sm540px
2md720px
3lg960px
4xl1140px
5xxl1320px

maar deze zijn ook aanpasbaar:

1ResponsivePics::setColumns(12);
2ResponsivePics::setGutter(30);
3ResponsivePics::setGridWidths([
4    'xs'     => 576,
5    'sm'     => 768,
6    'md'     => 992,
7    'lg'     => 1200,
8    'xl'     => 1400,
9    'xxl'    => 1600,
10    'xxxl'   => 1920
11]);

Stel dat je hoofdinhoud wordt weergegeven in een container met een maximale breedte en dat je op mobiel wilt dat de afbeelding alle kolommen vult, op tablets de helft van de kolommen en op desktops een derde van de kolommen. Hoe zou je dit normaal gesproken aanpakken? Gebruik je het standaard 'grote' afbeeldingsformaat en maak je het responsive met css?

1<style>
2    .image {
3      .my-grid-image {
4        max-width: 100%;
5        height: auto;
6      }
7    }
8</style>
9<main class="container">
10    <h1><?= the_title(); ?></h1>
11    <div class="row">
12      <article class="entry col-xs-12 col-md-6 col-lg-8">
13        <?= the_content(); ?>
14      </article>
15      <figure class="image col-xs-12 col-md-6 col-lg-4">
16      <?php
17        $img = get_field('grid-image', get_the_ID());
18        $img_alt = $img['alt'];
19        $img_large = $img['sizes']['large'];
20      ?>
21      <img class="my-grid-image" src="<?= esc_url($img_large); ?>" alt="<?= $img_alt; ?>" />
22      </figure>
23    </div>
24</main>

Als je de standaard $grid-widths gebruikt, zou je maximale containerbreedte 1320px zijn. Aangezien we slechts 4 van de 12 kolommen op grote schermen willen, zouden we dan over:

1((1320 / 12) * 4) – (2* 30) = 380px

Dit zou resulteren in een gedownscalede afbeelding van:

1(380/1024) * 100 = 37%

Onnodig te zeggen dat dit niet optimaal is.
Met Responsive Pics hoeven we voortaan alleen nog maar dit te doen:

1<?= ResponsivePics::get_image($img['id'], 'xs-12, md-6, lg-4'); ?>

wat resulteert in deze opmaak:

1<main class="container">
2    <h1><?= the_title(); ?></h1>
3    <div class="row">
4      <article class="entry col-xs-12 col-md-6 col-lg-8">
5        <?= the_content(); ?>
6      </article>
7      <figure class="image col-xs-12 col-md-6 col-lg-4">
8      <img
9        srcset="/app/uploads/2020/11/grid-image-446×301.jpg 446w,
10          /app/uploads/2020/11/grid-image-446×301@2x.jpg 892w,
11          /app/uploads/2020/11/grid-image-446×301.jpg 446w,
12          /app/uploads/2020/11/grid-image-446×301@2x.jpg 892w,
13          /app/uploads/2020/11/grid-image-380×256.jpg 380w,
14          /app/uploads/2020/11/grid-image-380×256@2x.jpg 760w,
15          /app/uploads/2020/11/grid-image-476×321.jpg 476w,
16          /app/uploads/2020/11/grid-image-476×321@2x.jpg 952w,
17          /app/uploads/2020/11/grid-image-748×504.jpg 748w,
18          /app/uploads/2020/11/grid-image-748×504@2x.jpg 1496w,
19          /app/uploads/2020/11/grid-image-556×375.jpg 556w,
20          /app/uploads/2020/11/grid-image-556×375@2x.jpg 1112w"
21        sizes="(min-width: 1400px) 446px,
22          (min-width: 1200px) 446px,
23          (min-width: 992px) 380px,
24          (min-width: 768px) 476px,
25          (min-width: 576px) 748px,
26          (min-width: 0px) 556px,
27          100vw"
28        src="/app/uploads/2020/11/grid-image.jpg"
29        alt="Grid system image example"
30      >
31      </figure>
32    </div>
33</main>

En nu hebben onze afbeeldingen exact dezelfde breedte als onze rasterwerkkolom op elke schermgrootte!

We kunnen zelfs onze eigen afbeeldingsklasse(n) doorgeven als 4e parameter:

1<?= ResponsivePics::get_image($img['id'], 'xs-12, md-6, lg-4', '', 'my-image-class'); ?>

Of schakel lazyload van de afbeelding in door de 5e parameter als true door te geven:

1<?= ResponsivePics::get_image($img['id'], 'xs-12, md-6, lg-4', '', 'my-image-class', true); ?>

Dit genereert de volgende opmaak:

1<img
2    class="my-image-class lazyload"
3    data-srcset="/app/uploads/2020/11/grid-image-446×301.jpg 446w,
4      /app/uploads/2020/11/grid-image-446×301@2x.jpg 892w,
5      /app/uploads/2020/11/grid-image-446×301.jpg 446w,
6      /app/uploads/2020/11/grid-image-446×301@2x.jpg 892w,
7      /app/uploads/2020/11/grid-image-380×256.jpg 380w,
8      /app/uploads/2020/11/grid-image-380×256@2x.jpg 760w,
9      /app/uploads/2020/11/grid-image-476×321.jpg 476w,
10      /app/uploads/2020/11/grid-image-476×321@2x.jpg 952w,
11      /app/uploads/2020/11/grid-image-748×504.jpg 748w,
12      /app/uploads/2020/11/grid-image-748×504@2x.jpg 1496w,
13      /app/uploads/2020/11/grid-image-556×375.jpg 556w,
14      /app/uploads/2020/11/grid-image-556×375@2x.jpg 1112w"
15    sizes="(min-width: 1400px) 446px,
16      (min-width: 1200px) 446px,
17      (min-width: 992px) 380px,
18      (min-width: 768px) 476px,
19      (min-width: 576px) 748px,
20      (min-width: 0px) 556px,
21      100vw"
22    src="/app/uploads/2020/11/grid-image.jpg"
23    alt="Grid system image example"
24>
Case 3: Art directed beeld

In bijna elk wordpress-sjabloon dat we ontwikkelen, hebben we ergens in de lay-out een art-directed afbeelding nodig. Dit kan zo eenvoudig zijn als het aanpassen van de grootte met verschillende maximale afbeeldingshoogten voor elk onderbrekingspunt, of het bijsnijden van een afbeelding met een andere verhouding vanaf een bepaald onderbrekingspunt.

Om dit te bereiken moeten we het element gebruiken. Onze plugin heeft daar een aparte functie voor genaamd get_picture waarmee we een hoogtefactor en/of bijsnijdposities kunnen definiëren voor elk onderbrekingspunt!

Laten we zeggen dat we een panoramische bannerafbeelding willen weergeven bovenaan onze hoofdinhoud. Zonder kunstrichting zou deze afbeelding erg smal worden op kleinere schermen, dus idealiter zou je de uitsnedeverhouding willen aanpassen om kleiner te worden als het scherm groter wordt. Gelukkig is dit supergemakkelijk:

1<main class="container">
2    <?= ResponsivePics::get_picture($banner, 'xs-12/0.75|c, md-12/0.5|c, lg-12/0.35|c'); ?>
3</main>

We kunnen zelfs het brandpunt van de uitsnede veranderen van linksboven naar het midden:

1<main class="container">
2    <?= ResponsivePics::get_picture($banner, 'xs-12/0.75|l t, md-12/0.5|c t, lg-12/0.35|c'); ?>
3</main>

Dit zou het volgende beeldelement creëren:

1<picture>
2    <source media="(min-width: 1400px)" srcset="/app/uploads/2020/11/art-banner-1380×482-center-center.jpg 1x, /app/uploads/2020/11/art-banner-1380×[email protected] 2x">
3    <source media="(min-width: 1200px)" srcset="/app/uploads/2020/11/art-banner-1380×482-center-center.jpg 1x, /app/uploads/2020/11/art-banner-1380×[email protected] 2x">
4    <source media="(min-width: 992px)" srcset="/app/uploads/2020/11/art-banner-1180×413-center-center.jpg 1x, /app/uploads/2020/11/art-banner-1180×[email protected] 2x">
5    <source media="(min-width: 768px)" srcset="/app/uploads/2020/11/art-banner-972×486-center-top.jpg 1x, /app/uploads/2020/11/art-banner-972×[email protected] 2x">
6    <source media="(min-width: 576px)" srcset="/app/uploads/2020/11/art-banner-748×561-left-top.jpg 1x, /app/uploads/2020/11/art-banner-748×[email protected] 2x">
7    <source media="(min-width: 0px)" srcset="/app/uploads/2020/11/art-banner-556×417-left-top.jpg 1x, /app/uploads/2020/11/art-banner-556×[email protected] 2x">
8    <img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Art directed banner example">
9</picture>

Je kunt zien dat voor deze afbeeldingsmethode ook automatisch retina-ondersteuning wordt toegevoegd! Omdat de verhouding van de afbeelding kan veranderen tijdens het wijzigen van het formaat van je scherm, kunnen we een extra 'intrinsieke' functionaliteit inschakelen door de 5e parameter als true door te geven:

1<main class="container">
2    <?= ResponsivePics::get_picture($banner, 'xs-12/0.75|l t, md-12/0.5|c t, lg-12/0.35|c', null, false, true); ?>
3</main>

Dit voegt wat extra data-aspectratio attributen toe aan de bronnen:

1<picture class="intrinsic">
2    <source media="(min-width: 1400px)" srcset="/app/uploads/2020/11/art-banner-1380x482-center-center.jpg 1x, /app/uploads/2020/11/art-banner-1380x482-center-center@2x.jpg 2x" data-aspectratio="2.8630705394191">
3    <source media="(min-width: 1200px)" srcset="/app/uploads/2020/11/art-banner-1380x482-center-center.jpg 1x, /app/uploads/2020/11/art-banner-1380x482-center-center@2x.jpg 2x"data-aspectratio="2.8630705394191">
4    <source media="(min-width: 992px)" srcset="/app/uploads/2020/11/art-banner-1180x413-center-center.jpg 1x, /app/uploads/2020/11/art-banner-1180x413-center-center@2x.jpg 2x" data-aspectratio="2.8571428571429">
5    <source media="(min-width: 768px)" srcset="/app/uploads/2020/11/art-banner-972x486-center-top.jpg 1x, /app/uploads/2020/11/art-banner-972x486-center-top@2x.jpg 2x" data-aspectratio="2">
6    <source media="(min-width: 576px)" srcset="/app/uploads/2020/11/art-banner-748x561-left-top.jpg 1x, /app/uploads/2020/11/art-banner-748x561-left-top@2x.jpg 2x" data-aspectratio="1.3333333333333">
7    <source media="(min-width: 0px)" srcset="/app/uploads/2020/11/art-banner-556x417-left-top.jpg 1x, /app/uploads/2020/11/art-banner-556x417-left-top@2x.jpg 2x" data-aspectratio="1.3333333333333">
8    <img class="intrinsic__item" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="Art directed banner example">
9</picture>

Hierdoor kun je de hoogte van de afbeelding vooraf berekenen met een plugin zoals lazysizes aspectratio extension voordat de afbeelding is geladen. Erg handig als je enkele documenthoogteberekeningen moet uitvoeren.

Case 4: Achtergrond headerafbeelding

Dus terug naar de full-width header use case. Deze keer willen we geen inline element gebruiken zoals een <img> of <picture>, maar een echte background-image zodat de header content de hoogte van de header bepaalt.

Als je dit eerder hebt geprobeerd zonder deze plugin, heb je waarschijnlijk ontdekt dat het bijna onmogelijk is om inline responsive achtergrondafbeeldingen direct in je sjablonen te maken.

1<?php
2$img_id = get_post_thumbnail_id();
3$img_header = wp_get_attachment_image_src($img_id, 'header'); 
4$img_header_retine = wp_get_attachment_image_src($img_id, 'header-retina'); 
5?>
6<header
7  class="my-header" 
8  style="background-image:url('<?= $img_header; ?>')"
9>
10  <h1 class="my-header__title"><?= the_title(); ?></h1>
11  <p class="my-header__excerpt"><?= the_excerpt(); ?></p> 
12</header>

Want hoe vertellen we de browser om onze retinaversie te gebruiken? Waar schrijven we onze css media-queries? Het antwoord is, dat kan niet. De enige oplossing is het maken van een inline (scoped?) css-blok met een unieke id selector waar je al je css media-queries toevoegt:

1<?php
2$img_id = get_post_thumbnail_id();
3$img_header = wp_get_attachment_image_src($img_id, 'header');
4$img_header_mobile = wp_get_attachment_image_src($img_id, 'header-mobile');
5$img_header_retine = wp_get_attachment_image_src($img_id, 'header-retina');
6?>
7<style scoped="scoped" type="text/css">
8  #my-header-<?= get_the_ID(); ?> {
9    background-image: url('<?= $img_header_mobile[0]; ?>');
10  }
11  @media (min-width: 640px) {
12    #my-header-<?= get_the_ID(); ?> {
13      background-image: url('<?= $img_header[0]; ?>');
14    }
15  }
16  @media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 640px), only screen and (min-resolution: 192dpi) and (min-width: 640px) {
17    #my-header-<?= get_the_ID(); ?> {
18      background-image: url('<?= $img_header_retine[0]; ?>');
19    }
20  }
21</style>
22<header
23  id="my-header-<?= get_the_ID(); ?>"
24  class="my-header"
25>
26  <h1 class="my-header__title"><?= the_title(); ?></h1>
27  <p class="my-header__excerpt"><?= the_excerpt(); ?></p>
28</header>

Dat is een hoop markup voor slechts 3 verschillende afbeeldingsbronnen!
Laten we dat vereenvoudigen met onze derde functie get_background:

1<header
2class="my-header"
3>
4<h1 class="my-header__title"><?= the_title(); ?></h1>
5<p class="my-header__excerpt"><?= the_excerpt(); ?></p>
6<?= ResponsivePics::get_background(get_post_thumbnail_id(), 'xs-full', 'my-header__bg'); ?>
7</header>

Dat zal de volgende opmaak voor je maken:

1<style scoped="scoped" type="text/css">
2@media (min-width: 0px) {
3#responsive-pics-background-581 {
4background-image: url("/app/uploads/2020/11/my-header-576×388.jpg");
5}
6}
7@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 0px), only screen and (min-resolution: 192dpi) and (min-width: 0px) {
8#responsive-pics-background-581 {
9background-image: url("/app/uploads/2020/11/my-header-576×[email protected]");
10}
11}
12@media (min-width: 576px) {
13#responsive-pics-background-581 {
14background-image: url("/app/uploads/2020/11/my-header-768×518.jpg");
15}
16}
17@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 576px), only screen and (min-resolution: 192dpi) and (min-width: 576px) {
18#responsive-pics-background-581 {
19background-image: url("/app/uploads/2020/11/my-header-768×[email protected]");
20}
21}
22@media (min-width: 768px) {
23#responsive-pics-background-581 {
24background-image: url("/app/uploads/2020/11/my-header-992×669.jpg");
25}
26}
27@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 768px), only screen and (min-resolution: 192dpi) and (min-width: 768px) {
28#responsive-pics-background-581 {
29background-image: url("/app/uploads/2020/11/my-header-992×[email protected]");
30}
31}
32@media (min-width: 992px) {
33#responsive-pics-background-581 {
34background-image: url("/app/uploads/2020/11/my-header-1200×810.jpg");
35}
36}
37@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 992px), only screen and (min-resolution: 192dpi) and (min-width: 992px) {
38#responsive-pics-background-581 {
39background-image: url("/app/uploads/2020/11/my-header-1200×[email protected]");0
40}
41}
42@media (min-width: 1200px) {
43#responsive-pics-background-581 {
44background-image: url("/app/uploads/2020/11/my-header-1400×945.jpg");
45}
46}
47@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 1200px), only screen and (min-resolution: 192dpi) and (min-width: 1200px) {
48#responsive-pics-background-581 {
49background-image: url("/app/uploads/2020/11/my-header-1400×[email protected]");
50}
51}
52@media (min-width: 1400px) {
53#responsive-pics-background-581 {
54background-image: url("/app/uploads/2020/11/my-header-1400×945.jpg");
55}
56}
57@media only screen and (-webkit-min-device-pixel-ratio: 2) and (min-width: 1400px), only screen and (min-resolution: 192dpi) and (min-width: 1400px) {
58#responsive-pics-background-581 {
59background-image: url("/app/uploads/2020/11/my-header-1400×[email protected]");}
60}
61}
62</style>
63<div class="my-header__bg" id="responsive-pics-background-581"></div>

Het enige nadeel van deze methode is dat je enkele afmetingen moet definiëren op de gegenereerde div of dat je hem absoluut moet positioneren:

1.my-header {
2position: relative;
3
4&__bg {
5position: absolute;
6left: 0;
7top: 0; 
8right: 0;
9bottom: 0; 
10z-index: -1;
11background-repeat: no-repeat;
12background-position: center;
13background-size: cover;
14}
15}

Natuurlijk zijn deze gebruikssituaties slechts een topje van de ijsberg. Met deze WordPress-tools creëer je moeiteloos complexe, responsieve lay-outs zonder zorgen over afbeeldingsprestaties in je template.

Achtergrondverwerking

Een andere belangrijke functie van onze plugin is dat het wijzigen van het formaat en het bijsnijden van de afbeeldingen worden toegevoegd als acties aan een wachtrij voor taken. Elke actie voert als een achtergrondtaak uit, zodat je webserver geen time-out krijgt. Dit proces wordt beheerd door de verbazingwekkende Action Scheduler bibliotheek. Action Scheduler heeft een ingebouwd WordPress beheerscherm voor het monitoren, debuggen en handmatig activeren van geplande acties.

Wij als digital agency hebben besloten om onze plugin openbaar te maken en beschikbaar op Github voor elke ontwikkelaar om te gebruiken. Op deze manier geven we iets terug aan het open-source WordPress ecosysteem dat ons de afgelopen tien jaar zoveel heeft gegeven!

Ga voor de volledige documentatie van de 3 methoden die ik zojuist heb geïntroduceerd naar de Responsive Pics website. Geef ons ook een ster op Github!