Użyj picture, aby przełączać się między kwadratowymi i szerokimi plikami obrazów przy określonym progu szerokości widoku. Podaj wymiary każdego źródła i pozwól CSS proporcjonalnie skalować wybrany obraz. W tym poradniku tworzysz i testujesz lokalny przykład na Macu.
Jak picture przełącza się między różnymi proporcjami obrazu?
Umieść element source z warunkiem media przed zapasowym elementem img wewnątrz picture. Przeglądarka wybiera pierwsze kwalifikujące się źródło, którego warunek jest spełniony, a następnie wybiera obraz z jego srcset. Nazywa się to ukierunkowaniem artystycznym: dostarczaniem różnych kompozycji dla różnych układów. Standard HTML wyraźnie obsługuje takie podejście. Standard HTML: obrazy
Współdziałają tu trzy elementy: źródło wybiera zasób, atrybuty wymiarów opisują jego proporcje, a CSS kontroluje rozmiar wyświetlania. Atrybuty width i height wybranego źródła mogą określać proporcje używane przez zawarty w nim obraz. Sam element picture nie wyświetla obrazu — robi to jego img. Standard HTML: zawartość osadzona
Wybierz mechanizm odpowiedni do oczekiwanego rezultatu:
| Wymaganie | Odpowiedni mechanizm |
|---|---|
| Zmiana kompozycji lub proporcji obrazu przy określonym progu szerokości | picture z elementem source używającym media |
| Różne rozdzielczości tej samej kompozycji | srcset, z sizes w przypadku użycia deskryptorów szerokości |
| Jeden plik przycinany do stałej ramki | Dopasowanie rozmiaru w CSS i object-fit: cover |
Mechanizmy te służą do podejmowania różnych decyzji. Ukierunkowanie artystyczne określa, która kompozycja zostanie wyświetlona. Wybór rozdzielczości pozwala przeglądarce wybrać odpowiedni wariant w ramach danej kompozycji. Dopasowanie w CSS określa, jak wybrany zasób wypełnia ramkę. MDN opisuje te zastosowania picture oraz jego związek z srcset i właściwościami dopasowania. MDN: element picture
Utwórz kompletny lokalny przykład na Macu
Przykład wykorzystuje dwa oryginalne zasoby SVG: jeden zawiera pomarańczowe koło i turkusowy zaokrąglony prostokąt. W wersji kwadratowej kształty są ułożone jeden nad drugim, a w szerokiej obok siebie. Wszystkie pliki znajdują się w jednym folderze; przełączanie nie wymaga zewnętrznych zasobów ani JavaScriptu.
Prosta umowa dotycząca zasobów wygląda tak: przy szerokości widoku poniżej 700px używany jest zasób kwadratowy o wymiarach 600 × 600. Przy 700px i więcej — szeroki zasób o wymiarach 1200 × 600. Wyświetlany obraz wypełnia obszar treści z marginesem 16px po każdej stronie, a jego maksymalna szerokość wynosi 960px. Te wymiary i próg szerokości są przykładowymi decyzjami projektowymi.
Zapisz dwa zasoby z kształtami
Utwórz folder o nazwie picture-demo. W edytorze kodu obsługującym zwykły tekst utwórz w nim dwa poniższe pliki, zachowując dokładne nazwy i rozszerzenia. Każdy blok kodu zawiera kompletną zawartość pliku; skopiuj ją bez znaczników bloku Markdown.
Zapisz jako 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>
Zapisz jako 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>
Zapisz stronę HTML
Utwórz index.html w tym samym folderze. Jeśli używasz TextEdit, wybierz File > New, a następnie Format > Make Plain Text przed wklejeniem kodu. Zapisz plik z rozszerzeniem .html i w razie wyświetlenia monitu wybierz Use .html. Apple opisuje ten sposób tworzenia plików HTML. Apple: Praca z dokumentami HTML w TextEdit na Macu
<!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>
Otwórz index.html w Safari. Przy odpowiednio szerokim widoku kształty powinny być ułożone obok siebie. Przy węższym widoku powinny znaleźć się jeden nad drugim. Trzymaj wszystkie trzy pliki razem: względne adresy zasobów są rozwiązywane względem lokalizacji pliku HTML.
Szerokie źródło używa srcset, mimo że zawiera tylko jeden URL. Wewnątrz picture element source wymaga srcset; jego atrybut src jest niedozwolony. Atrybuty wymiarów są liczbami całkowitymi bez jednostek, więc użyj width="1200", a nie width="1200px". MDN: element source
Dlaczego podawać wymiary zarówno źródła, jak i obrazu zapasowego?
Wymiary 600 × 600 obrazu zapasowego opisują zasób kwadratowy. Wymiary 1200 × 600 szerokiego źródła opisują zasób szeroki. Podanie obu par pozwala przeglądarce obsługującej tę funkcję ustalić proporcje wybranego obrazu przed jego pobraniem. Użycie wymiarów kwadratowych dla szerokiego źródła podałoby błędne początkowe proporcje. Standard HTML: atrybuty wymiarów źródła
CSS ustawia następnie szerokość obrazu na szerokość dostępnego obszaru treści, pozostawiając automatyczną wysokość. Dzięki temu proporcje obrazu określają jego wysokość. Projekt specyfikacji CSS dotyczący rozmiarów opisuje, jak preferowane proporcje wpływają na automatyczne ustalanie rozmiaru; jawne ustalenie obu wymiarów odbiera tę elastyczność. Moduł CSS Box Sizing, poziom 4
W tym przykładzie układ można sprawdzić za pomocą prostego obliczenia:
szerokość obrazu = min(szerokość widoku - 32, 960)
wysokość obrazu kwadratowego = szerokość obrazu
wysokość obrazu szerokiego = szerokość obrazu / 2
| Szerokość widoku w pikselach CSS | Wybrany zasób | Obliczony rozmiar obrazu |
|---|---|---|
| 500 | shapes-square.svg |
468 × 468 |
| 699 | shapes-square.svg |
667 × 667 |
| 700 | shapes-wide.svg |
668 × 334 |
| 1000 | shapes-wide.svg |
960 × 480 |
Są to wartości obliczone na podstawie podanego CSS, przy założeniu, że szerokość paska przewijania nie zmniejsza dostępnego obszaru treści. Składnię SVG, nazwy zasobów, zadeklarowane wymiary i obliczenia sprawdzono programowo; podczas przygotowywania przykładu nie renderowano go w przeglądarce.
Zwróć uwagę na dużą zmianę wysokości między 699px a 700px. Wynika ona bezpośrednio z przejścia z kompozycji kwadratowej na szeroką. Taka zmiana jest oczekiwana podczas zmiany rozmiaru widoku. Jeśli po załadowaniu pojawi się kolejny skok przy niezmienionej szerokości widoku, sprawdź zadeklarowane wymiary i ewentualny nadpisujący je CSS.
Dokładne testowanie progu szerokości w Safari
Tryb Responsive Design w Safari pozwala zmieniać rozmiar widoku strony niezależnie od rozmiaru okna na pulpicie. W ustawieniach Advanced Safari włącz Show features for web developers. Otwórz przykład, a następnie wybierz Develop > Enter Responsive Design Mode lub naciśnij Control-Command-R. WebKit opisuje to ustawienie, skrót i podgląd o regulowanym rozmiarze. WebKit: uproszczony tryb Responsive Design
Najpierw przetestuj 699px i 700px, a potem wygodnie wąski i szeroki widok. Sprawdź, czy kompozycja zmienia się na zamierzonej granicy, pomarańczowy kształt pozostaje kołem, a akapit pod obrazem podąża za zmianą jego wysokości. Odśwież stronę po obu stronach progu, aby sprawdzić zarówno początkowy układ, jak i jego zmianę podczas zmiany rozmiaru.
Aby bezpośrednio sprawdzić, który plik wybrało Safari, uruchom opcjonalny fragment diagnostyczny w konsoli Web Inspector podczas wyświetlania przykładu:
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
});
Uruchom fragment ponownie po przekroczeniu progu. Wybrany URL powinien kończyć się odpowiednią nazwą pliku kwadratowego lub szerokiego. Właściwość currentSrc zwraca URL wybrany przez przeglądarkę; sama jej wartość nie dowodzi, że zasób został poprawnie załadowany. MDN: właściwość currentSrc obiektu HTMLImageElement
Co sprawdzić, gdy przełączanie nie działa prawidłowo?
Sprawdzaj po kolei wybór, wymiary zasobu i sposób wyświetlania. Dzięki temu problemu z rozmiarem w CSS nie pomylisz z problemem wyboru zasobu.
- Przy szerokim widoku nadal wybierany jest plik kwadratowy. Sprawdź, czy szerokość widoku osiąga
700px, czysourcewystępuje przedimgoraz czy źródło używasrcset. Jeśli jest wiele źródeł, sprawdź ich kolejność: pierwszeństwo może mieć wcześniejsze źródło, którego warunek jest spełniony. Standard HTML: wybór według ukierunkowania artystycznego - Zasób się nie pojawia. Porównaj nazwy plików w znacznikach z plikami w folderze, uwzględniając rozszerzenia. W tym przykładzie oba pliki SVG muszą znajdować się obok
index.html. - Wyświetlany jest właściwy zasób, ale ma nieprawidłowy kształt. Sprawdź reguły CSS zastosowane do właściwego
img, zwłaszcza te, które przypisują stałą wysokość. Aby zachować proporcje, przywróćheight: auto. - Po załadowaniu obraz przeskakuje. Porównaj każdą zadeklarowaną parę wymiarów z rzeczywistymi proporcjami zasobu. Sprawdź też, czy jawna właściwość CSS
aspect-rationie nadpisuje zamierzonych proporcji.
Jeśli projekt wymaga stałej ramki, świadomie wybierz sposób dopasowania. object-fit: contain zachowuje cały zasób i może pozostawić puste miejsce; cover wypełnia ramkę i może przyciąć zawartość; fill może ją rozciągnąć. Stosuj właściwości dopasowania do img. Podany przykład nie wymaga stałej ramki, ponieważ układ dopasowuje się do proporcji wybranego zasobu. MDN: object-fit
Jakie są ograniczenia obsługi przez przeglądarki?
Obsługa picture i obsługa wymiarów właściwych dla poszczególnych źródeł to osobne kwestie. Zestawienie zgodności w standardzie HTML wymienia picture we współczesnych silnikach przeglądarek. MDN oznacza właściwość źródła width, która odzwierciedla jego atrybut wymiaru, jako dostępną we wszystkich przeglądarkach od grudnia 2022 r. Nie należy zakładać, że starsze przeglądarki poprawnie zarezerwują miejsce na wymiary właściwe dla źródła. Standard HTML: element picture, MDN: właściwość width obiektu HTMLSourceElement
Gdy żadne źródło nie pasuje albo przeglądarka nie obsługuje picture, obraz dostarcza zapasowy img. W tym przykładzie jest to kompozycja kwadratowa. Przeglądarka, która przełącza zasoby, ale nie obsługuje wymiarów źródła, może ustalić ostateczne proporcje szerokiego obrazu dopiero po jego załadowaniu. MDN: element picture
Jeśli docelowa przeglądarka obsługuje CSS aspect-ratio, ale wymaga jawnej reguły rozmiaru, dodaj poniższy fragment CSS na końcu istniejącego arkusza stylów. Odzwierciedla on próg szerokości HTML i podaje tymczasowe proporcje, pozwalając, by po załadowaniu zaczęły obowiązywać naturalne proporcje obrazu:
.study-image {
aspect-ratio: auto 1 / 1;
}
@media (min-width: 700px) {
.study-image {
aspect-ratio: auto 2 / 1;
}
}
MDN opisuje takie połączenie auto z proporcjami i podaje, że CSS aspect-ratio jest obsługiwany we wszystkich przeglądarkach od września 2021 r. Fragment ma więc własne ograniczenie dotyczące obsługi. Zachowaj zgodność jego progu szerokości z warunkiem źródła i przetestuj wersje przeglądarek, które musisz uwzględnić. MDN: aspect-ratio
Gdy przykład działa poprawnie, zastąp przykładowe pliki własnymi kompozycjami i odpowiednio zaktualizuj ich wymiary. Zachowaj zgodność warunku źródła, proporcji zasobów i reguł CSS określających rozmiar, a następnie ponownie sprawdź szerokości bezpośrednio poniżej i powyżej progu.
Źródła
- Standard HTML: obrazy — WHATWG
- Standard HTML: zawartość osadzona — WHATWG
- Moduł CSS Box Sizing, poziom 4 — W3C CSS Working Group
<picture>: element Picture — MDN Web Docs<source>: element Media lub Image Source — MDN Web Docs- HTMLSourceElement: właściwość width — MDN Web Docs
- HTMLImageElement: właściwość currentSrc — MDN Web Docs
- Właściwość CSS object-fit — MDN Web Docs
- Właściwość CSS aspect-ratio — MDN Web Docs
- Praca z dokumentami HTML w TextEdit na Macu — Apple
- Uproszczony tryb Responsive Design — WebKit