Lekcja 14

Media queries i breakpointy

W poprzedniej lekcji poznałeś podejście mobile-first. Teraz skupiamy się na narzędziu, które pozwala rozszerzać layout w konkretnych momentach: media queries oraz świadomie dobranych breakpointach.

Cele lekcji

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

  • napisać podstawowe @media dla szerokości viewportu,
  • wyjaśnić różnicę między min-width i max-width,
  • dobrać breakpoint na podstawie treści, a nie nazwy urządzenia,
  • zaplanować małą skalę breakpointów dla projektu,
  • ograniczać liczbę reguł responsywnych do realnie potrzebnych zmian.

Kontekst praktyczny

Media queries pojawiają się wtedy, gdy jeden układ nie wystarcza dla wszystkich szerokości. Używasz ich do zmiany liczby kolumn, układu nawigacji, wielkości odstępów, szerokości paneli albo zachowania elementów pobocznych.

W praktyce: breakpoint jest decyzją projektową. Dodaj go wtedy, gdy treść zaczyna wyglądać źle albo ma za mało miejsca, nie dlatego, że chcesz obsłużyć konkretny model telefonu.

Czym jest media query

Media query to warunek w CSS. Reguły wewnątrz @media działają tylko wtedy, gdy przeglądarka spełnia podany warunek, na przykład ma viewport szerszy niż 760px.

Najczęstszy warunek w responsywności dotyczy szerokości ekranu, ale media queries mogą reagować także na preferencje użytkownika, typ urządzenia albo możliwości wejścia.

Składnia @media

Podstawowy zapis wygląda tak:

.card-list {
  display: grid;
  gap: 1rem;
}

@media (min-width: 760px) {
  .card-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .card-list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

Najpierw definiujesz styl bazowy. Potem dokładane są reguły dla większych szerokości. CSS nadal działa kaskadowo: późniejszy pasujący breakpoint może nadpisać wcześniejsze ustawienie.

min-width w mobile-first

min-width oznacza: „zastosuj te reguły od tej szerokości wzwyż”. To naturalnie pasuje do podejścia mobile-first, bo style bazowe obsługują telefon, a większe viewporty dostają dodatkowe możliwości.

.lesson-sidebar {
  display: none;
}

@media (min-width: 900px) {
  .lesson-sidebar {
    display: block;
  }
}

Takie podejście zmniejsza liczbę wyjątków. Nie musisz najpierw budować desktopu, a później go „odkręcać” dla telefonu.

max-width i wyjątki

max-width oznacza: „zastosuj te reguły do tej szerokości w dół”. Może być przydatny przy naprawie konkretnego problemu na małych ekranach, ale w kursie jako główny wzorzec przyjmujemy min-width.

Zapamiętaj: mieszanie wielu min-width i max-width bez jasnego planu szybko tworzy trudną do przewidzenia kaskadę.

Dobór breakpointów

Dobry breakpoint wynika z treści. Jeśli karta robi się zbyt wąska, menu nie mieści się w jednym rzędzie albo sidebar zabiera miejsce głównej treści, to znak, że layout potrzebuje zmiany.

  • Nie ustawiaj breakpointu tylko dlatego, że istnieje tablet o konkretnej szerokości.
  • Sprawdzaj układ płynnie, przeciągając szerokość viewportu w DevTools.
  • Dodawaj breakpoint dopiero wtedy, gdy prosty układ przestaje być czytelny.
  • Testuj szerokości pomiędzy popularnymi rozmiarami, nie tylko same wartości graniczne.

Prosta skala breakpointów

W małym projekcie wystarczą zwykle dwa albo trzy punkty zmiany. Przykładowa skala może wyglądać tak:

  • 480px — małe rozszerzenia dla większych telefonów,
  • 760px — przejście na układy dwukolumnowe,
  • 1024px — pełniejszy desktop, więcej kolumn i sidebar,
  • 1200px — dopracowanie szerokich widoków, jeśli treść naprawdę tego potrzebuje.

W czystym CSS nie możesz użyć zwykłej zmiennej CSS bezpośrednio w warunku @media. Dlatego taką skalę warto dokumentować konsekwentnie w komentarzach, planie projektu albo design tokens, a wartości w media queries wpisywać jawnie.

Zmiana layoutu sekcji

Poniższy przykład pokazuje typowy wzorzec: najpierw jedna kolumna, potem układ z treścią i panelem bocznym dopiero wtedy, gdy viewport ma wystarczająco dużo miejsca.

.article-shell {
  display: grid;
  gap: 1rem;
}

.article-aside {
  padding: 1rem;
  border: 1px solid #dbe2f1;
  border-radius: 12px;
}

@media (min-width: 900px) {
  .article-shell {
    grid-template-columns: minmax(0, 1fr) 18rem;
    align-items: start;
  }

  .article-aside {
    position: sticky;
    top: 1rem;
  }
}

To nie jest breakpoint „dla laptopa”. To breakpoint dla momentu, w którym treść i panel boczny mogą żyć obok siebie bez ściskania głównej kolumny.

Demo breakpointów

Poniższe demo pokazuje, jak ten sam zestaw kart może zmieniać się na trzech szerokościach: od jednej kolumny, przez dwie, do trzech.

Base < 760px
Tablet min 760px
Desktop min 1024px

Interpretacja: kod nie musi znać nazwy urządzenia. Wystarczy, że reaguje na moment, w którym layout ma przestrzeń na kolejne kolumny.

Debugowanie responsywności

Przy każdej zmianie responsywnej sprawdzaj kilka rzeczy:

  • czy strona nie ma poziomego przewijania,
  • czy tekst w kartach nie wypycha kolumn,
  • czy interaktywne elementy mają wystarczająco dużo miejsca,
  • czy layout działa także pomiędzy breakpointami,
  • czy ostatni breakpoint nie nadpisuje przypadkiem zbyt wielu reguł.

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

  • Dodawanie breakpointu dla każdego popularnego urządzenia.
  • Używanie max-width i min-width bez konsekwentnej strategii.
  • Przenoszenie zbyt wielu reguł do media query zamiast zmiany tylko tego, co konieczne.
  • Zakładanie, że 768px zawsze oznacza tablet, a 1024px zawsze desktop.
  • Brak testowania przestrzeni pomiędzy breakpointami.
  • Traktowanie media queries jako zamiennika dla elastycznych układów grid, flex, min() i minmax().

Mini zadanie

Rozbuduj sekcję kart z Lekcji 13 o świadomie dobrane breakpointy.

  • Zostaw bazowo jedną kolumnę.
  • Dodaj breakpoint od 760px i ustaw dwie kolumny.
  • Dodaj breakpoint od 1024px i ustaw trzy kolumny.
  • Przetestuj szerokości 390px, 760px, 900px, 1024px i 1280px.
  • Usuń każdy breakpoint, który nie poprawia czytelności layoutu.

Checklista

  • Potrafię napisać media query z min-width.
  • Rozumiem, kiedy użyć max-width jako wyjątku.
  • Dobieram breakpointy na podstawie treści i czytelności layoutu.
  • Nie tworzę osobnego breakpointu dla każdego urządzenia.
  • Testuję szerokości pomiędzy breakpointami.
  • Wiem, że custom properties nie działają bezpośrednio w warunku @media.

Podsumowanie lekcji

Media queries pozwalają zmieniać layout wtedy, gdy viewport spełnia konkretny warunek. W podejściu mobile-first najczęściej używasz min-width, startujesz od prostego układu i dokładasz złożoność dopiero tam, gdzie treść ma na nią miejsce.

Kolejny krok roadmapy to jednostki CSS: px, %, em, rem, vw, vh, svh i ch.

Przejdź do Lekcji 15