Lekcja 16

Obrazy i media responsywne

Obrazy potrafią zniszczyć dobry layout szybciej niż źle dobrany breakpoint. W tej lekcji nauczysz się zabezpieczać media przed overflow, utrzymywać proporcje i kontrolować kadrowanie bez utraty czytelności UI.

Cele lekcji

Po ukończeniu tej lekcji będziesz umieć:

  • ustawić bezpieczny bazowy styl dla obrazów, wideo i osadzonych mediów,
  • używać max-width: 100% i height: auto bez deformowania grafiki,
  • kontrolować proporcje komponentów przez aspect-ratio,
  • stosować object-fit i object-position do świadomego kadrowania,
  • rozumieć rolę picture, srcset i sizes w responsywnych obrazach,
  • ograniczać skoki layoutu przez atrybuty width i height.

Kontekst praktyczny

Responsywne media pojawiają się w kartach produktów, zdjęciach artykułów, galeriach, sekcjach hero, avatarach, dashboardach i materiałach edukacyjnych. Ten sam obraz może wyglądać dobrze na desktopie, ale na telefonie wypchnąć layout poza viewport albo uciąć najważniejszy fragment.

W praktyce: obraz nie powinien dyktować całego layoutu. To komponent powinien określać dostępną szerokość, proporcje i sposób kadrowania, a obraz ma się do tego bezpiecznie dopasować.

Bazowy styl mediów

Najważniejszy reset dla obrazów jest krótki. Zabezpiecza przed poziomym overflow i usuwa problem pustej przestrzeni pod obrazem wynikający z domyślnego zachowania elementów inline.

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

img,
video {
  height: auto;
}

max-width: 100% pozwala obrazowi zmniejszyć się do szerokości rodzica, a height: auto zachowuje jego naturalne proporcje.

Proporcje i aspect-ratio

W kartach, galeriach i hero często potrzebujesz stabilnego miejsca na obraz, zanim grafika się wczyta. aspect-ratio pozwala zarezerwować przewidywalny format bez ręcznego liczenia wysokości.

.media-card__image {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 12px;
}

.media-card__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

Najczęściej spotkasz proporcje 16 / 9 dla szerokich kadrów, 4 / 3 dla klasycznych zdjęć i 1 / 1 dla avatarów lub miniatur.

object-fit i kadrowanie

object-fit mówi przeglądarce, jak obraz ma wypełnić ramkę, kiedy ramka i obraz mają inne proporcje.

  • cover — obraz wypełnia całą ramkę, ale może zostać przycięty.
  • contain — cały obraz jest widoczny, ale w ramce mogą pojawić się puste pasy.
  • fill — obraz wypełnia ramkę i może zostać zniekształcony, więc zwykle go unikamy.
  • object-position — ustawia punkt kadrowania, np. center, top albo 60% 40%.
Zapamiętaj: cover jest świetne dla kart i hero, ale wymaga kontroli kadru. Jeśli obraz zawiera tekst, wykres albo interfejs, często lepsze jest contain.

picture, srcset i sizes

Responsywność obrazu to nie tylko CSS. HTML może pomóc przeglądarce wybrać właściwy wariant grafiki dla danego viewportu i gęstości ekranu.

<picture>
  <source
    media='(min-width: 760px)'
    srcset='assets/img/hero-wide.webp'>
  <img
    src='assets/img/hero-mobile.webp'
    alt='Panel aplikacji pokazany na responsywnym ekranie'
    width='720'
    height='960'
    loading='lazy'
    decoding='async'>
</picture>

picture jest przydatny przy art direction, czyli gdy na mobile pokazujesz inny kadr niż na desktopie. srcset i sizes pomagają natomiast dobrać rozdzielczość obrazu do realnej szerokości renderowania.

Ładowanie i stabilność layoutu

Responsywne obrazy powinny być nie tylko elastyczne, ale też przewidywalne. Dwa atrybuty mają tu duże znaczenie:

  • width i height — pozwalają przeglądarce obliczyć proporcje przed pobraniem pliku,
  • loading="lazy" — opóźnia ładowanie obrazów poza pierwszym viewportem,
  • decoding="async" — pozwala przeglądarce dekodować obraz bez blokowania renderowania.

Nie stosuj loading="lazy" automatycznie do głównego obrazu hero w pierwszym widoku. Tam obraz jest częścią pierwszego renderu i powinien być dostępny szybko.

Demo responsywnych mediów

Poniższe demo pokazuje trzy decyzje: stabilną proporcję, kadr zależny od viewportu oraz różnicę między cover i contain.

.media-card__frame {
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

.media-card__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
Stabilna proporcja aspect-ratio: 16 / 9
Szeroki abstrakcyjny kadr użyty jako przykład obrazu responsywnego
Inny kadr dla desktopu picture + source
Responsywny obraz zmieniający kadr między mobile i desktopem
Kadrowanie cover kontra contain
cover Przykład object-fit cover
contain Przykład object-fit contain

Interpretacja: pierwszy przykład rezerwuje miejsce przez proporcje, drugi pokazuje zmianę źródła obrazu przez picture, a trzeci pokazuje, dlaczego cover przycina kadr, a contain zostawia cały obraz widoczny.

Najczęstsze błędy początkujących

  • Ustawianie samego width: 100% bez height: auto dla zwykłego obrazu.
  • Sztywna szerokość obrazu w px, która powoduje poziome przewijanie na mobile.
  • Używanie height: 100% bez wysokości rodzica i bez kontroli proporcji.
  • Stosowanie object-fit: cover do obrazów z tekstem, wykresami albo ważnymi detalami na krawędziach.
  • Brak atrybutu alt albo opis alternatywny, który nie mówi, co obraz wnosi do treści.
  • Brak width i height, przez co layout skacze podczas ładowania obrazów.

Mini zadanie

Zbuduj responsywną kartę artykułu z obrazem.

  • Dodaj ramkę obrazu z aspect-ratio: 16 / 9.
  • Ustaw obraz na width: 100%, height: 100% i object-fit: cover.
  • Dodaj alt, width, height, loading="lazy" i decoding="async".
  • Na większym breakpointcie zmień układ karty z jednej kolumny na obraz + treść obok siebie.
  • Sprawdź w devtools, czy na szerokości 390px nie pojawia się poziome przewijanie.

Checklista

  • Potrafię zabezpieczyć obraz przed wyjściem poza kontener.
  • Rozumiem różnicę między max-width: 100% i sztywną szerokością.
  • Umiem użyć aspect-ratio do stabilnej ramki obrazu.
  • Wiem, kiedy użyć cover, a kiedy contain.
  • Rozumiem podstawową rolę picture, srcset i sizes.
  • Pamiętam o alt, width, height i świadomym ładowaniu obrazów.

Podsumowanie lekcji

Responsywne media wymagają kontroli szerokości, proporcji, kadrowania i ładowania. Bazowy styl chroni przed overflow, aspect-ratio stabilizuje układ, object-fit kontroluje kadr, a picture, srcset i sizes pomagają dostarczyć właściwy obraz do właściwego ekranu.

Kolejny krok roadmapy to fluid typography i funkcje min(), max() oraz clamp().

Przejdź do Lekcji 17