Obrazy elastyczne

Tekst na stronach internetowych automatycznie zawija się do krawędzi ekranu, dzięki czemu nie wychodzi poza krawędź ekranu. Inaczej jest w przypadku obrazów. Obrazy mają naturalny rozmiar. Jeśli obraz jest szerszy niż ekran, wychodzi on poza ekran, co powoduje wyświetlenie poziomego paska przewijania.

Na szczęście możesz zapobiec takim sytuacjom w CSS.

Ograniczanie zdjęć

W arkuszu stylów możesz zadeklarować, że obrazy nigdy nie powinny być renderowane w rozmiarze szerszym niż ich element zawierający element max-inline-size.

Obsługa przeglądarek

  • 57
  • 79
  • 41
  • 12.1

Źródło

img {
  max-inline-size: 100%;
  block-size: auto;
}

Możesz zastosować tę samą regułę również do innych rodzajów treści umieszczanych na stronach, takich jak filmy czy elementy iframe.

img,
video,
iframe {
  max-inline-size: 100%;
  block-size: auto;
}

Po zastosowaniu tej reguły przeglądarki będą automatycznie pomniejszać obrazy w dół, aby pasowały do ekranu.

Dwa zrzuty ekranu. Pierwszy przedstawia obraz rozwijany poza szerokość przeglądarki, a drugi ten sam obraz ograniczony w widocznym obszarze przeglądarki.

Dodanie wartości block-size o wartości auto oznacza, że współczynnik proporcji obrazów pozostanie stały.

Czasami wymiary obrazu mogą wydawać się poza naszą kontrolą, np. dodanie go poprzez system zarządzania treścią. Jeśli projekt wymaga, by obrazy miały współczynnik proporcji inny niż ich rzeczywiste wymiary, użyj w CSS właściwości aspect-ratio.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
}

Wtedy przeglądarka może jednak zściskać lub rozciągnąć obraz, aby uzyskać dopasowanie do preferowanego formatu obrazu.

Profil przystojnego, szczęśliwego psa z kłębkiem w pysku, ale zdjęcie jest ściśnięte.

Aby temu zapobiec, używaj właściwości object-fit.

Obsługa przeglądarek

  • 32
  • 79
  • 36
  • 10

Źródło

Wartość object-fit wynosząca contain informuje przeglądarkę, że ma zachować współczynnik proporcji obrazu, nawet jeśli oznacza to pozostawienie pustego obszaru powyżej i pod nim.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: contain;
}

Wartość object-fit wynosząca cover informuje przeglądarkę, że ma zachować format obrazu nawet wtedy, gdy oznacza to przycięcie obrazu u góry i dołu.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
}
Profil przystojnego szczęśliwego psa z kulką w pysku. Po obu stronach obrazu jest więcej miejsca. Profil przystojnego, szczęśliwego psa z piłką w pysku. Zdjęcie zostało przycięte u góry i na dole.
Ten sam obraz z 2 różnymi wartościami atrybutu „object-fit”. Pierwszy ma wartość „object-fit” o wartości „contain”. Drugi ma wartość „cover” jako „obiektu”.

Jeśli problem powoduje przycinanie równomiernie u góry i u dołu, użyj właściwości CSS object-position, aby dostosować ostrość przycięcia.

Obsługa przeglądarek

  • 32
  • 79
  • 36
  • 10

Źródło

Dzięki temu najważniejsze treści graficzne będą nadal widoczne.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
  object-position: top center;
}

Profil przystojnego, szczęśliwego psa z kłębkiem w pysku. Zdjęcie zostało przycięte tylko u dołu.

Przesyłanie obrazów

Te reguły CSS informują przeglądarkę, jak mają być renderowane obrazy. W kodzie HTML możesz też umieścić wskazówki na temat tego, jak przeglądarka powinna postępować z tymi obrazami.

Wskazówki dotyczące rozmiaru

Jeśli znasz wymiary zdjęcia, musisz użyć atrybutów width i height. Nawet wtedy, gdy obraz jest renderowany w innym rozmiarze (z powodu reguły max-inline-size: 100%), przeglądarka nadal zna stosunek szerokości do wysokości i może zostawić odpowiednią ilość miejsca. Dzięki temu inne treści nie będą skakać podczas wczytywania obrazu.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
>
Pierwszy film przedstawia układ bez zdefiniowanych wymiarów obrazu. Zwróć uwagę na to, że tekst przesuwa się po wczytaniu obrazów. W drugim filmie podano wymiary obrazu. Teraz jest miejsce na obraz, aby po wczytaniu tekst nie skakał.

Wczytuję wskazówki

Atrybut loading pozwala wskazać przeglądarce, czy ma opóźnić wczytywanie obrazu do momentu znalezienia się w widocznym obszarze lub w jego pobliżu. W przypadku obrazów w części strony widocznej po przewinięciu użyj wartości lazy. Przeglądarka nie będzie wczytywała leniwych obrazów, dopóki użytkownik nie przewinie strony na tyle daleko, aby obraz mógł się pojawić. Jeśli użytkownik nigdy nie przewinie strony, obraz nie zostanie wczytany.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
>

W przypadku banera powitalnego w części strony widocznej na ekranie nie należy używać atrybutu loading. Jeśli w witrynie automatycznie stosujesz atrybut loading="lazy", możesz często ustawić atrybut eager (czyli domyślny), by temu zapobiec:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
>

Priorytet pobierania

W przypadku ważnych obrazów, takich jak obraz LCP, możesz dodatkowo określić priorytet wczytywania za pomocą Priorytetu pobierania, ustawiając atrybut fetchpriority na high:

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 fetchpriority="high"
>

Spowoduje to, że przeglądarka pobierze obraz od razu, z najwyższym priorytetem, bez oczekiwania na zakończenie układu, gdy obrazy są normalnie pobierane.

Pamiętaj jednak, że gdy poprosisz przeglądarkę o priorytetowe pobieranie jednego zasobu (np. obrazu), przeglądarka musi obniżyć priorytet innego zasobu, takiego jak skrypt lub plik czcionek. Atrybut fetchpriority="high" dotyczący obrazu ustawiaj tylko wtedy, gdy jest on naprawdę istotny.

Wskazówki dotyczące wstępnego wczytywania

Niektóre obrazy mogą nie być dostępne w początkowym kodzie HTML, jeśli zostały dodane przez JavaScript lub jako obraz tła w CSS. Możesz też skorzystać z funkcji wstępnego wczytywania, aby umożliwić wcześniejsze pobranie tych ważnych obrazów. Możesz go połączyć z atrybutem fetchpriority w przypadku bardzo ważnych obrazów:

<link rel="preload" href="hero.jpg" as="image" fetchpriority="high">

Również w tym przypadku należy używać tej funkcji z umiarem, aby nie zastępować heurystyki ustalania priorytetów w przeglądarkach, co może skutkować spadkiem wydajności.

Wstępne wczytywanie obrazów elastycznych na podstawie atrybutu srcset (opisanego poniżej) za pomocą atrybutów imagesrcset i imagesizes jest bardziej zaawansowane i obsługiwane w niektórych przeglądarkach, ale nie we wszystkich:

Wykluczając wartość zastępczą href, możesz mieć pewność, że przeglądarki, które nie obsługują tej funkcji, nie wczytują wstępnie nieprawidłowego obrazu.

Wstępne wczytywanie na podstawie różnych formatów obrazów w zależności od obsługi tych obrazów przez przeglądarkę nie jest obecnie obsługiwane i może spowodować pobieranie dodatkowych plików.

Najlepiej jest unikać wstępnego wczytywania, gdy jest to możliwe, i udostępniać obraz w początkowym kodzie HTML, aby uniknąć powtarzania kodu i umożliwić dostęp do pełnego zakresu opcji obsługiwanych przez przeglądarkę.

Dekodowanie obrazu

Dostępny jest też atrybut decoding, który możesz dodać do elementów img. Możesz poinformować przeglądarkę, że obraz można dekodować asynchronicznie. Przeglądarka może następnie nadać priorytet przetwarzaniu innych treści.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
>

Możesz użyć wartości sync, jeśli sam obraz jest najważniejszym elementem treści, na którym należy potraktować priorytetowo.

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 decoding="sync"
>

Atrybut decoding nie zmienia szybkości dekodowania obrazu, a jedynie to, czy przeglądarka czeka na dekodowanie tego obrazu przed wyrenderowaniem innych treści.

W większości przypadków nie ma to większego wpływu, ale w niektórych przypadkach może umożliwić szybsze wyświetlanie obrazu lub treści. Na przykład w przypadku dużego dokumentu z wieloma elementami, których renderowanie wymaga dużo czasu, a także z dużymi obrazami, których dekodowanie zajmuje więcej czasu, ustawienie sync na ważnych obrazach spowoduje, że przeglądarka będzie czekać na obraz i wyrenderować oba elementy jednocześnie. Natomiast ustawienie async może przyspieszyć wyświetlanie treści bez oczekiwania na dekodowanie obrazu.

Jednak lepszym rozwiązaniem jest zwykle unikanie nadmiernej wielkości DOM i korzystanie z obrazów elastycznych, co pozwoli skrócić czas dekodowania. Dzięki temu atrybut dekodowania będzie miał niewielki wpływ.

Elastyczne obrazy z wykorzystaniem srcset

Dzięki tej deklaracji max-inline-size: 100% Twoje obrazy nigdy nie wychodzą poza kontenery. Jednak nawet jeśli obraz na dużym ekranie wygląda dobrze, a mimo to pomniejsza się, by zmieścić się w kadrze, nie będzie to zgrabne. Jeśli ktoś korzysta z małego ekranu w sieci o niskiej przepustowości, może pobrać niepotrzebnie duże obrazy.

Jeśli tworzysz wiele wersji tego samego obrazu w różnych rozmiarach, możesz poinformować o nich przeglądarkę za pomocą atrybutu srcset.

Deskryptor szerokości

Możesz przekazać listę wartości rozdzielonych przecinkami. Każda wartość powinna być adresem URL obrazu, po którym następuje spacja, a po niej pewne metadane obrazu. Metadane te są nazywane deskryptorem.

W tym przykładzie metadane opisują szerokość każdego obrazu za pomocą jednostki w. Jeden w to 1 piksel.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
>

Atrybut srcset nie zastępuje atrybutu src. Zamiast tego atrybut srcset uzupełnia atrybut src. Nadal musisz mieć prawidłowy atrybut src, ale teraz przeglądarka może zastąpić jego wartość jedną z opcji wymienionych w atrybucie srcset.

Przeglądarka nie pobierze większych obrazów, jeśli nie są potrzebne. Oszczędza to przepustowość.

Rozmiary

Jeśli używasz deskryptora szerokości, musisz też użyć atrybutu sizes, aby przekazać przeglądarce więcej informacji. Informuje ona przeglądarkę o oczekiwanym rozmiarze obrazu w różnych warunkach. Te warunki są określone w zapytaniu o multimedia.

Atrybut sizes zawiera listę rozdzielonych przecinkami zapytań o media i szerokości obrazów.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
 sizes="(min-width: 66em) 33vw,
  (min-width: 44em) 50vw,
  100vw"
>

W tym przykładzie informujesz przeglądarkę, że ponad szerokość widocznego obszaru, wynosząca 66em, jest tak duża, aby obraz nie był szerszy niż jedna trzecia ekranu (np. w układzie 3-kolumnowym).

Jeśli szerokość widocznego obszaru wynosi od 44em do 66em, wyświetl obraz na połowę szerokości ekranu (w układzie 2-kolumnowym).

W przypadku elementów poniżej 44em wyświetla się obraz na całą szerokość ekranu.

Oznacza to, że nawet największy obraz nie musi być używany na największym ekranie. Szerokie okno przeglądarki, w którym można wyświetlać układ wielokolumnowy, użyje obrazu mieszczącego się w jednej kolumnie. Obraz może być mniejszy niż obraz używany w układzie jednokolumnowym na węższym ekranie.

Deskryptor gęstości pikseli

W innej sytuacji możesz chcieć dostarczyć wiele wersji tego samego obrazu.

Niektóre urządzenia mają ekrany o dużej gęstości. Na wyświetlaczu o podwójnej gęstości możesz umieścić dwa piksele w obszarze jednego piksela. Zapewnia to ostrość obrazów na wyświetlaczach tego typu.

Dwie wersje tego samego zdjęcia przystojnego szczęśliwego psa z kłębkiem w pysku: jedna ostre, a druga niewyraźna.

Użyj deskryptora gęstości, aby opisać gęstość pikseli obrazu w stosunku do obrazu w atrybucie src. Deskryptor gęstości to liczba, po której następuje litera x: 1x, 2x itd.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 1x,
  medium-image.png 2x,
  large-image.png 3x"
>

Jeśli small-image.png ma rozmiar 300 x 200 pikseli, a medium-image.png – 600 x 400 pikseli, po elemencie medium-image.png na liście srcset może znajdować się 2x.

Nie musisz używać liczb całkowitych. Jeśli inna wersja obrazu ma rozmiar 450 x 300 pikseli, możesz go opisać za pomocą atrybutu 1.5x.

Obrazy prezentacyjne

Obrazy w języku HTML są treścią. Dlatego zawsze należy podać atrybut alt z opisem obrazu dla czytników ekranu i wyszukiwarek.

Jeśli umieścisz w witrynie obraz, który jest tylko wizualnym rozmachem, a nie zawiera żadnej istotnej treści, użyj pustego atrybutu alt.

<img
 src="flourish.png"
 alt=""
 width="400"
 height="50"
>

Mimo to musisz dodać atrybut alt. Brakujący atrybut alt różni się od pustego atrybutu alt. Pusty atrybut alt informuje czytnik ekranu, że obraz jest prezentacyjny.

Najlepiej w ogóle nie umieszczać obrazów prezentacyjnych ani dekoracyjnych w kodzie HTML. HTML to struktura. CSS służy do prezentacji.

Obrazy tła

Do wczytywania obrazów prezentacyjnych używaj właściwości background-image w CSS.

element {
  background-image: url(flourish.png);
}

Możesz wskazać kilka obrazów do wyświetlenia, korzystając z funkcji image-set w funkcji background-image.

Funkcja image-set w CSS działa podobnie jak atrybut srcset w kodzie HTML. Podaj listę obrazów z deskryptorem gęstości pikseli dla każdego z nich.

element {
  background-image: image-set(
    small-image.png 1x,
    medium-image.png 2x,
    large-image.png 3x
  );
}

Przeglądarka wybierze obraz najbardziej odpowiedni do gęstości pikseli na ekranie urządzenia.

Dodając obrazy do witryny, musisz wziąć pod uwagę wiele czynników:

Zarezerwowanie odpowiedniej przestrzeni dla każdego obrazu. Ustalam, ile rozmiarów potrzebujesz. Zdecyduj, czy obraz ma charakter treści czy ozdobny.

Warto poświęcić trochę czasu na dopracowanie zdjęć. Złe strategie dotyczące obrazów są odpowiedzialne za frustrację i irytację użytkowników. Dobra strategia dotycząca obrazów sprawia, że witryna jest szybka i ostra, niezależnie od urządzenia, z którego korzysta użytkownik, czy też połączenia sieciowego.

W zestawie narzędzi jest jeszcze jeden element HTML, który pozwala lepiej kontrolować obraz: element picture.

Sprawdź swoją wiedzę

Sprawdź swoją wiedzę o obrazach

Aby obrazy mieściły się w widocznym obszarze, należy dodać style.

Prawda
Obrazy, które nie zawierają pomieszczeń ochronnych, będą miały taki sam rozmiar, jak ich naturalny rozmiar.
Fałsz
Style są wymagane.

Jeśli wysokość i szerokość obrazu zostaną wymuszone do nienaturalnych proporcji, które style mogą pomóc w dostosowaniu obrazu do tych proporcji?

object-fit
Określ, jak obraz pasuje do słów kluczowych, takich jak contain i cover.
image-fit
Ta usługa nie istnieje.
fit-image
Ta usługa nie istnieje.
aspect-ratio
Może to spowodować lub rozwiązać problem z nienaturalnym formatem obrazu.

Jeśli umieścisz w obrazach atrybuty height i width, CSS nie będzie mógł zmieniać ich stylu.

Prawda
Traktuj je raczej jak wskazówki niż reguły.
Fałsz
CSS udostępnia wiele dynamicznych opcji określania rozmiaru obrazów, nawet jeśli wysokość i szerokość są wbudowane w tag.

Atrybut srcset nie _______ atrybutu src, tylko _______.

uzupełniają, zastępuje
srcset z pewnością nie zastępuje atrybutu src.
zastępować, uzupełnia
Jeśli przeglądarka obsługuje taką funkcję, udostępnia ona dodatkowe opcje do wyboru.

Brak atrybutu alt na obrazie jest taki sam jak pusty element alt.

Prawda
Pusty atrybut alt informuje czytnik ekranu, że obraz jest prezentacyjny
Fałsz
Brak wartości alt nie sygnalizuje czytnika ekranu.