Gebruik picture om bij een viewportbreekpunt te wisselen tussen vierkante en brede afbeeldingsbestanden. Geef elke bron eigen afmetingen en laat CSS de geselecteerde afbeelding proportioneel schalen. In deze handleiding bouw en test je een lokaal voorbeeld op een Mac.

Hoe schakelt picture tussen verschillende beeldverhoudingen?

Plaats een element source met een voorwaarde media vóór de fallback img binnen picture. De browser selecteert de eerste in aanmerking komende bron waarvan de voorwaarde overeenkomt en selecteert vervolgens een afbeelding uit de srcset van die bron. Dit heet art direction: verschillende composities aanbieden voor verschillende lay-outs. De HTML Standard ondersteunt deze aanpak expliciet. HTML Standard: Images

Drie onderdelen werken samen: de bron kiest de afbeelding, dimensieattributen beschrijven de verhoudingen van die afbeelding en CSS bepaalt de weergavegrootte. De width en height van de geselecteerde bron kunnen de beeldverhouding leveren die wordt gebruikt door de ingesloten afbeelding. Het element picture zelf geeft de afbeelding niet weer; dat doet zijn img. HTML Standard: Embedded content

Kies het mechanisme op basis van het gewenste resultaat:

Je vereiste Geschikt mechanisme
De compositie of beeldverhouding wijzigen bij een breekpunt picture met een source die media gebruikt
Verschillende resoluties van dezelfde compositie aanbieden srcset, met sizes bij gebruik van breedtedescriptors
Eén bestand behouden, maar het bijsnijden binnen een vast kader CSS-formaatinstellingen en object-fit: cover

Deze mechanismen beantwoorden verschillende vragen. Art direction bepaalt welke compositie wordt weergegeven. Met resolutieselectie kan de browser binnen een compositie een geschikte kandidaat kiezen. CSS-aanpassing bepaalt hoe de geselecteerde afbeelding het kader vult. MDN beschrijft deze toepassingen van picture en de relatie ervan met srcset en aanpassingseigenschappen. MDN: The picture element

Maak een volledig lokaal voorbeeld op je Mac

Het voorbeeld gebruikt twee originele SVG-afbeeldingen met een oranje cirkel en een afgeronde turquoise rechthoek. In de vierkante versie staan ze boven elkaar; in de brede versie staan ze naast elkaar. Alles staat in één map; voor het wisselen zijn geen externe bestanden of JavaScript nodig.

De specificatie van de afbeeldingen is eenvoudig: gebruik onder een viewportbreedte van 700px een vierkante afbeelding van 600 × 600. Bij 700px en breder gebruik je een brede afbeelding van 1200 × 600. De weergegeven afbeelding vult een inhoudsgebied met aan weerszijden 16px ruimte, tot een maximale breedte van 960px. Deze afmetingen en het breekpunt zijn illustratieve ontwerpkeuzes.

Sla de twee vormbestanden op

Maak een map met de naam picture-demo. Maak met een gewone teksteditor de volgende twee bestanden daarin en behoud exact de opgegeven namen en extensies. Elk codeblok bevat het volledige bestand; kopieer de inhoud zonder de Markdown-hekjes.

Sla dit op als shapes-square.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
  <rect width="600" height="600" fill="#fff5df"/>
  <circle cx="300" cy="180" r="100" fill="#de7b35"/>
  <rect x="150" y="340" width="300" height="160" rx="40" fill="#247d83"/>
</svg>

Sla dit op als shapes-wide.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="600" viewBox="0 0 1200 600">
  <rect width="1200" height="600" fill="#fff5df"/>
  <circle cx="320" cy="300" r="180" fill="#de7b35"/>
  <rect x="650" y="150" width="400" height="300" rx="60" fill="#247d83"/>
</svg>

Sla de HTML-pagina op

Maak index.html in dezelfde map. Kies je voor TextEdit, selecteer dan File > New en vervolgens Format > Make Plain Text voordat je de code plakt. Sla het bestand op met de extensie .html en kies indien daarom wordt gevraagd Use .html. Apple beschrijft deze werkwijze voor het maken van HTML-bestanden. Apple: Work with HTML documents in TextEdit on Mac

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Shape study</title>
  <style>
    body { margin: 0; font-family: system-ui, sans-serif; }
    main { width: calc(100% - 32px); max-width: 960px; margin: 24px auto; }
    picture { display: block; }
    .study-image { display: block; width: 100%; height: auto; }
  </style>
</head>
<body>
  <main>
    <h1>Shape study</h1>
    <picture>
      <source media="(min-width: 700px)" srcset="shapes-wide.svg"
              width="1200" height="600">
      <img class="study-image" src="shapes-square.svg"
           width="600" height="600"
           alt="An orange circle and a teal rounded rectangle on cream.">
    </picture>
    <p>Resize the viewport to compare the two arrangements.</p>
  </main>
</body>
</html>

Open index.html in Safari. Bij een voldoende brede viewport moeten de vormen naast elkaar staan. Bij een smallere viewport moeten ze boven elkaar staan. Houd alle drie de bestanden bij elkaar: de relatieve URL's van de afbeeldingen verwijzen naar de locatie van het HTML-bestand.

De brede bron gebruikt srcset, ook al bevat deze maar één URL. Binnen picture vereist source srcset; het kenmerk src is daar niet toegestaan. Dimensieattributen zijn gehele getallen zonder eenheden, dus gebruik width="1200", niet width="1200px". MDN: The source element

Waarom geef je dimensies op voor zowel de bron als de fallback?

De afmetingen 600 × 600 van de fallback beschrijven de vierkante afbeelding. De afmetingen 1200 × 600 van de brede bron beschrijven de brede afbeelding. Als je beide paren opgeeft, kan een browser die dit ondersteunt de verhoudingen van de geselecteerde afbeelding vaststellen voordat deze wordt gedownload. Als je voor de brede bron de vierkante afmetingen zou gebruiken, levert dat aanvankelijk de verkeerde verhouding op. HTML Standard: Source dimension attributes

De CSS stelt de breedte van de afbeelding vervolgens in op de beschikbare inhoudsbreedte, terwijl de hoogte automatisch blijft. Daardoor bepaalt de verhouding van de afbeelding de hoogte. Het conceptdocument CSS Sizing beschrijft hoe een voorkeursbeeldverhouding een rol speelt bij automatische afmetingen; als je beide afmetingen expliciet vastlegt, verdwijnt die flexibiliteit. CSS Box Sizing Module Level 4

Voor dit voorbeeld kun je de lay-out controleren met een eenvoudige berekening:

breedte afbeelding = min(viewportbreedte - 32, 960)
hoogte vierkant = breedte afbeelding
hoogte breed = breedte afbeelding / 2
Viewportbreedte in CSS-pixels Geselecteerde afbeelding Berekende afbeeldingsgrootte
500 shapes-square.svg 468 × 468
699 shapes-square.svg 667 × 667
700 shapes-wide.svg 668 × 334
1000 shapes-wide.svg 960 × 480

Dit zijn berekende verwachtingen voor de opgegeven CSS, ervan uitgaande dat de scrollbarbreedte het beschikbare inhoudsgebied niet verkleint. De SVG-syntaxis, bestandsnamen, opgegeven afmetingen en berekeningen zijn programmatisch gecontroleerd; het voorbeeld is tijdens de voorbereiding niet in een browser weergegeven.

Let op de grote verandering in hoogte tussen 699px en 700px. Die volgt rechtstreeks uit de omschakeling van een vierkante naar een brede compositie. Dat is te verwachten wanneer je het venster vergroot of verkleint. Als de afbeelding na het laden nogmaals van hoogte verandert terwijl de viewport gelijk blijft, controleer dan de opgegeven afmetingen en eventuele CSS die ze overschrijft.

Test het breekpunt precies in Safari

Met Safari's Responsive Design Mode kun je de viewport van de pagina aanpassen, onafhankelijk van het bureaubladvenster. Schakel in Safari's instellingen onder Advanced de optie Show features for web developers in. Open vervolgens het voorbeeld en kies Develop > Enter Responsive Design Mode, of druk op Control-Command-R. WebKit beschrijft de instelling, sneltoets en aanpasbare voorbeeldweergave. WebKit: Simplified Responsive Design Mode

Test eerst 699px en 700px, en daarna een duidelijk smalle en brede viewport. Controleer of de compositie op de bedoelde grens verandert, de oranje vorm rond blijft en de alinea onder de afbeelding meeschuift met de veranderende hoogte. Laad de pagina aan beide kanten van het breekpunt opnieuw om zowel de initiële lay-out als het aanpassen van de viewport te controleren.

Voer dit optionele diagnostische fragment uit in de console van Web Inspector terwijl je het voorbeeld bekijkt om rechtstreeks te controleren welk bestand Safari heeft geselecteerd:

const studyImage = document.querySelector('.study-image');
if (!studyImage) {
  throw new Error('Open the Shape study example before running this snippet.');
}
const studyBox = studyImage.getBoundingClientRect();
console.table({
  selectedURL: studyImage.currentSrc,
  displayedWidth: studyBox.width,
  displayedHeight: studyBox.height
});

Voer het fragment opnieuw uit nadat je het breekpunt bent gepasseerd. De geselecteerde URL moet eindigen op de bijbehorende naam van het vierkante of brede bestand. De eigenschap currentSrc meldt de URL die de browser heeft gekozen; de waarde ervan bewijst op zichzelf niet dat de afbeelding met succes is geladen. MDN: HTMLImageElement currentSrc property

Wat moet je controleren als het wisselen niet goed gaat?

Controleer achtereenvolgens de selectie, de afmetingen van de afbeeldingen en de weergave. Zo voorkom je dat een probleem met de CSS-afmetingen wordt aangezien voor een probleem met de afbeeldingsselectie.

  1. Het vierkante bestand blijft geselecteerd bij brede viewports. Controleer of de viewport 700px bereikt, of source vóór img staat en of de bron srcset gebruikt. Controleer bij meerdere bronnen de volgorde: een eerdere bron waarvan de voorwaarde overeenkomt, kan voorrang krijgen. HTML Standard: Art direction selection
  2. Een afbeelding wordt niet weergegeven. Vergelijk de bestandsnamen in de markup met de bestanden in de map, inclusief extensies. Voor dit voorbeeld moeten beide SVG-bestanden naast index.html staan.
  3. De juiste afbeelding wordt in de verkeerde vorm weergegeven. Controleer de CSS die op het daadwerkelijke element img wordt toegepast, vooral regels die een vaste hoogte instellen. Herstel height: auto voor proportionele afmetingen.
  4. De afbeelding verspringt na het laden. Vergelijk elk opgegeven afmetingenpaar met de werkelijke verhouding van de bijbehorende afbeelding. Controleer ook of een expliciete CSS-aspect-ratio de bedoelde verhoudingen overschrijft.

Als je ontwerp daadwerkelijk een vast kader vereist, kies dan bewust hoe de afbeelding daarin past. object-fit: contain behoudt de volledige afbeelding en kan lege ruimte overlaten; cover vult het kader en kan inhoud afsnijden; fill kan de afbeelding uitrekken. Pas aanpassingseigenschappen toe op img. Het opgegeven voorbeeld heeft geen vast kader nodig, omdat de lay-out de verhoudingen van de geselecteerde afbeelding volgt. MDN: object-fit

Welke beperkingen gelden voor browserondersteuning?

Ondersteuning voor picture en ondersteuning voor dimensies die specifiek zijn voor een bron zijn afzonderlijke aandachtspunten. Het compatibiliteitsoverzicht van de HTML Standard vermeldt picture in huidige browserengines. MDN geeft aan dat de eigenschap width van de bron, die het dimensieattribuut weerspiegelt, sinds december 2022 in browsers beschikbaar is. Ga er bij oudere browsers niet van uit dat ze dimensies die specifiek zijn voor een bron correct reserveren. HTML Standard: The picture element, MDN: HTMLSourceElement width property

Als geen bron overeenkomt, of als de browser picture niet ondersteunt, levert de fallback img de afbeelding. In dit voorbeeld is dat de vierkante compositie. Een browser die wel tussen afbeeldingen wisselt maar geen dimensiespecifieke bronondersteuning heeft, kan de uiteindelijke verhoudingen van de brede afbeelding mogelijk pas na het laden vaststellen. MDN: The picture element

Voor een browser die CSS aspect-ratio ondersteunt, maar een expliciete afmetingsregel nodig heeft, voeg je het volgende CSS-fragment toe aan de bestaande stylesheet. Het komt overeen met het HTML-breekpunt en geeft voorlopige verhoudingen op, terwijl de natuurlijke verhouding van de geladen afbeelding het uiteindelijk overneemt:

.study-image {
  aspect-ratio: auto 1 / 1;
}

@media (min-width: 700px) {
  .study-image {
    aspect-ratio: auto 2 / 1;
  }
}

MDN documenteert deze combinatie van auto en een verhouding en vermeldt dat CSS aspect-ratio sinds september 2021 in browsers beschikbaar is. Ook voor dit fragment geldt dus een ondersteuningsgrens. Houd het breekpunt gelijk aan de bronvoorwaarde en test de browserversies waarvoor je ondersteuning nodig hebt. MDN: aspect-ratio

Zodra het voorbeeld goed werkt, vervang je de tijdelijke bestanden door je eigen composities en werk je ook hun afmetingen bij. Houd de bronvoorwaarde, de verhoudingen van de afbeeldingen en de CSS-afmetingen op elkaar afgestemd en herhaal de controles direct onder en boven het breekpunt.

Bronnen