Menu

Media queries CSS: breakpointy, min-width i max-width

Media query stosuje CSS tylko wtedy, gdy spełniony jest warunek, na przykład minimalna szerokość ekranu, ciemny motyw albo wskaźnik myszy. Poznaj składnię @media, breakpointy mobile first, składnię zakresów, prefers-color-scheme, matchMedia w JavaScripcie i container queries.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Media query w jednym przykładzie

Media query otacza CSS warunkiem. Reguły wewnątrz @media (min-width: 600px) działają tylko wtedy, gdy viewport ma co najmniej 600px szerokości:

Podgląd to ramka, a media query wewnątrz niej mierzy ramkę, a nie twój ekran. Na komputerze ma ona mniej więcej szerokość kolumny tego artykułu, zwykle ponad 600px, więc pudełko jest niebieskie. Zwęź okno przeglądarki tak, żeby ramka spadła poniżej 600px, a pudełko zmieni kolor na bursztynowy; linijka pod pudełkiem na żywo podaje szerokość ramki. Na telefonie ramka jest już wąska, więc widzisz wersję bursztynową.

Składnia @media

@media (min-width: 600px) { ... }                        /* one condition */
@media (min-width: 600px) and (max-width: 899px) { ... } /* both must be true */
@media (max-width: 599px), print { ... }                 /* either one (comma = or) */
@media not print { ... }                                 /* negation */
@media screen and (orientation: landscape) { ... }       /* media type plus a feature */
@media (width >= 600px) { ... }                          /* range syntax */
@media (600px <= width < 900px) { ... }                  /* a range with both ends */

and wymaga spacji po obu stronach: (min-width: 600px)and(max-width: 900px) jest nieprawidłowe i całe zapytanie zostaje zignorowane. Składnia zakresów (width >= 600px) jest obsługiwana w aktualnych wersjach Chrome, Firefoksa i Safari i czyta się ją łatwiej niż min-width, zwłaszcza przy "do, ale bez".

Funkcje, których będziesz używać najczęściej:

FunkcjaPasuje, gdyPrzykład
min-width / width >=viewport ma co najmniej tę szerokość(min-width: 768px)
max-width / width <=viewport ma co najwyżej tę szerokość(max-width: 767px)
orientationportrait (wyższy niż szeroki) lub landscape(orientation: landscape)
hovergłówny wskaźnik może najeżdżać (hover) lub nie (none, większość ekranów dotykowych)(hover: hover)
pointergłówny wskaźnik jest fine (mysz) lub coarse (palec)(pointer: coarse)
prefers-color-schemeużytkownik wybrał motyw dark lub light(prefers-color-scheme: dark)
prefers-reduced-motionużytkownik poprosił system o mniej ruchu(prefers-reduced-motion: reduce)
print (typ mediów)strona jest drukowana lub zapisywana jako PDF@media print

Mobile first: breakpointy min-width

Napisz układ na telefon jako bazowy CSS, a potem dodaj zapytania min-width, które zmieniają układ, gdy przybywa miejsca. Każde zapytanie musi opisać tylko to, co się zmienia:

W szerokim oknie na komputerze podgląd ma ponad 720px, więc widzisz trzy kolumny; linijka pod siatką podaje szerokość i liczbę kolumn. Zwęź okno, a poniżej 720px zostaną dwie kolumny, a poniżej 480px jedna. Kolejność obu zapytań ma znaczenie: na szerokim ekranie oba są prawdziwe i wygrywa późniejsze, więc zapytania min-width idą od najmniejszego do największego. (Przy zapytaniach max-width jest odwrotnie: najpierw największe.)

Wybór breakpointów

Nie ma oficjalnej listy. Oto popularne wartości i to, co zwykle rozdzielają:

BreakpointZwykle
min-width: 640pxduże telefony w poziomie, małe tablety
min-width: 768pxtablety w pionie
min-width: 1024pxtablety w poziomie, małe laptopy
min-width: 1280pxkomputery stacjonarne

Lepsza metoda: zacznij od wąskiego układu, poszerzaj okno, aż coś zacznie źle wyglądać (za długie linie, za szerokie karty), i tam postaw breakpoint. Dla większości stron wystarczą dwa lub trzy breakpointy. Często nie potrzebujesz żadnego: repeat(auto-fit, minmax(200px, 1fr)) w grid, flex-wrap i clamp() dopasowują się płynnie.

Każda strona potrzebuje metatagu viewport

Bez tego tagu w <head> przeglądarki na telefonach układają stronę tak, jakby ekran miał około 980px szerokości, a potem ją oddalają, więc twoje zapytanie min-width: 480px jest zawsze prawdziwe, a układ na telefon nigdy się nie pokazuje:

<meta name="viewport" content="width=device-width, initial-scale=1">

Strona o meta viewport wyjaśnia każdą jego wartość.

Tryb ciemny z prefers-color-scheme

prefers-color-scheme podąża za jasnym lub ciemnym ustawieniem systemu operacyjnego. Najczystszy sposób użycia to trzymanie kolorów w zmiennych CSS i zmienianie wewnątrz zapytania tylko zmiennych:

W tym podglądzie zapytanie może wypisać false, nawet gdy system ma ustawiony ciemny motyw: Chrome nie przekazuje ustawienia systemu do izolowanej ramki takiej jak ta. Przycisk ustawia te same zmienne ręcznie, tak jak działa przełącznik motywu na stronie. :root[data-theme] jest bardziej specyficzny niż zwykły :root wewnątrz zapytania, więc wybór czytelnika wygrywa z systemem. Zapisz przykład jako plik i otwórz go, żeby zobaczyć, jak zapytanie podąża za systemem.

Skrypt pokazuje drugą połowę media queries: matchMedia() uruchamia to samo zapytanie z JavaScriptu, zwraca, czy teraz pasuje, i wywołuje zdarzenie change, gdy odpowiedź się zmienia. Używaj go, gdy od ekranu zależy zachowanie (a nie tylko wygląd), na przykład inny sposób otwierania menu na urządzeniach dotykowych.

Z ruchem jest tak samo. Duże lub zapętlone animacje umieszczaj w sprawdzeniu prefers-reduced-motion, jak pokazuje strona o animacjach.

Container queries: gdy decydować ma komponent

Media query zna tylko viewport. Karta, która na tej samej stronie stoi w szerokiej kolumnie głównej i w wąskim panelu bocznym, musi zamiast tego znać własną przestrzeń. Do tego służy container query: oznacz rodzica przez container-type: inline-size, a potem użyj @container z tymi samymi warunkami.

Przeciągnij róg szarego pudełka, żeby zmienić jego rozmiar. Karta zmienia układ przy 360px szerokości pudełka, bez względu na rozmiar okna:

Przy początkowych 480px obrazek stoi obok tekstu. Zwęź pudełko poniżej 376px (360px treści plus 8px paddingu z każdej strony), a obrazek przesunie się nad tekst. Container queries działają we wszystkich aktualnych głównych przeglądarkach.

Style do druku

@media print działa tylko wtedy, gdy strona jest drukowana lub zapisywana jako PDF. Ukryj nawigację i przyciski i użyj ciemnego tekstu na białym tle:

@media print {
  nav, .ad, button { display: none; }
  body { color: black; background: white; }
  a::after { content: " (" attr(href) ")"; } /* print the URL after each link */
}

Częste błędy

  • Brak metatagu viewport. Telefony zgłaszają wtedy szeroki viewport układu i zapytania dla małych ekranów nigdy nie pasują.
  • Zapytania w złej kolejności. Dwa prawdziwe zapytania z tym samym selektorem: wygrywa późniejsze. Układaj zapytania min-width od małych do dużych.
  • Nakładające się lub rozłączne granice. max-width: 768px i min-width: 768px pasują oba przy dokładnie 768px. Użyj w jednym z nich 767px albo składni zakresów (width < 768px) i (width >= 768px).
  • Brak spacji po and. and( jest nieprawidłowe i zapytanie po cichu przepada.
  • Testowanie tylko przez zmianę rozmiaru okna na komputerze. Sprawdź też prawdziwy telefon albo tryb urządzenia w przeglądarce, który stosuje viewport, gęstość pikseli i dotyk telefonu.
  • Za dużo breakpointów. Jeśli każdy komponent potrzebuje własnego, spróbuj zamiast tego auto-fit w grid, flex-wrap albo container queries.

Najczęściej zadawane pytania

Czym jest media query w CSS?

To reguła, która stosuje zawarty w niej CSS tylko wtedy, gdy spełniony jest warunek dotyczący urządzenia lub okna. @media (min-width: 600px) { ... } stosuje swoje style tylko wtedy, gdy viewport ma co najmniej 600px szerokości, i właśnie tak jedna strona dopasowuje się od telefonów po komputery.

Używać media queries z min-width czy z max-width?

Większość stron pisze się w podejściu mobile first: bazowy CSS jest dla małych ekranów, a zapytania min-width dodają układ, gdy ekran rośnie. Zapytania max-width działają odwrotnie, zaczynając od układu na komputer. Oba podejścia działają; mieszanie obu na tym samym elemencie prowadzi do nakładania się i luk na granicach.

Jakie są standardowe breakpointy w media queries?

Nie ma oficjalnego standardu. Popularne wartości to około 640px, 768px, 1024px i 1280px, ale lepsza zasada to dodawać breakpoint tam, gdzie twój własny układ zaczyna źle wyglądać, i trzymać liczbę breakpointów na niskim poziomie.

Dlaczego moje media query nie działa na telefonie?

Najczęstszą przyczyną jest brak metatagu viewport. Bez <meta name="viewport" content="width=device-width, initial-scale=1"> mobilne przeglądarki udają, że strona ma około 980px szerokości, więc zapytania dla małych szerokości nigdy nie pasują. Sprawdź też, czy zapytanie stoi po regułach, które nadpisuje.

Jak napisać media query dla trybu ciemnego?

Użyj @media (prefers-color-scheme: dark) { ... }. Pasuje, gdy system operacyjny lub przeglądarka użytkownika ma ustawiony ciemny motyw, a wewnątrz możesz nadpisać kolory albo zmienne CSS.

Czym różnią się media queries od container queries?

Media query sprawdza viewport (całe okno). Container query, zapisywane przez @container, sprawdza rozmiar elementu rodzica, który oznaczasz przez container-type: inline-size. Używaj container queries dla komponentu, który pojawia się na tej samej stronie zarówno w szerokich, jak i wąskich miejscach.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ