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.
- Het vierkante bestand blijft geselecteerd bij brede viewports. Controleer of de viewport
700pxbereikt, ofsourcevóórimgstaat en of de bronsrcsetgebruikt. Controleer bij meerdere bronnen de volgorde: een eerdere bron waarvan de voorwaarde overeenkomt, kan voorrang krijgen. HTML Standard: Art direction selection - 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.htmlstaan. - De juiste afbeelding wordt in de verkeerde vorm weergegeven. Controleer de CSS die op het daadwerkelijke element
imgwordt toegepast, vooral regels die een vaste hoogte instellen. Herstelheight: autovoor proportionele afmetingen. - 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-ratiode 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
- HTML Standard: Images — WHATWG
- HTML Standard: Embedded content — WHATWG
- CSS Box Sizing Module Level 4 — W3C CSS Working Group
<picture>: The Picture element — MDN Web Docs<source>: The Media or Image Source element — MDN Web Docs- HTMLSourceElement: width property — MDN Web Docs
- HTMLImageElement: currentSrc property — MDN Web Docs
- object-fit CSS property — MDN Web Docs
- aspect-ratio CSS property — MDN Web Docs
- Work with HTML documents in TextEdit on Mac — Apple
- Simplified Responsive Design Mode — WebKit