Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чому медіа-запити потрібні в CSS». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Медіа-запити** (media queries) - це CSS-правила, які застосовують різні стилі залежно від характеристик пристрою: ширини екрану або кольорової схеми. ```css .grid { grid-template-columns: 1fr; } @media (min-width: 768px) { .grid { grid-template-columns: repeat(3, 1fr); } } ``` **Головне:** без них один макет ламається на кожному розмірі екрану поза цільовим діапазоном.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Медіа-запити** (media queries) - це CSS-правила, які застосовують стилі залежно від характеристик пристрою: ширини екрану, орієнтації або кольорової схеми. ## Теорія ### TL;DR - Медіа-запити як офіціант, що подає різні порції залежно від столика: та сама страва, але розмір підлаштовується під потреби. Базові стилі для всіх, окремі правила для вузьких екранів. - Без них один CSS-файл нав'язує однаковий макет усім пристроям. Три колонки на 1440px перетворюються на нечитабельну кашу на 375px телефоні. - `max-width` - для desktop-first, `min-width` - для mobile-first (рекомендований підхід). - Спрацьовують миттєво при зміні розміру вікна, без JavaScript. ### Швидкий приклад ```css /* Базово: 3 колонки на десктопі */ .card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; } /* Телефон: екран вужчий за 600px → одна колонка */ @media (max-width: 600px) { .card-grid { grid-template-columns: 1fr; /* картки складаються вертикально, без горизонтального скролу */ } } ``` На десктопі три картки стоять поряд. На iPhone 375px вони складаються в один стовпець автоматично. ### Чому фіксовані стилі не працюють CSS без медіа-запитів фіксує один макет для всіх пристроїв. Браузер обирає один набір правил і застосовує його всюди, незалежно від розміру екрану. Медіа-запити дозволяють браузеру перевірити реальний viewport під час рендерингу і активувати тільки ті блоки правил, які підходять. Один файл стилів, різна поведінка на кожному пристрої. ### Коли використовувати - Mobile-first: базові стилі для мобільних, потім `@media (min-width: 768px)` для ширших екранів. - Стилі для друку: `@media print { .no-print { display: none; } }` прибирає навігацію зі сторінки при друці. - Темна тема: `@media (prefers-color-scheme: dark) { body { background: #000; } }`. - Орієнтація: `@media (orientation: landscape) { video { height: 100vh; } }`. - Доступність: `@media (prefers-reduced-motion: reduce) { * { animation: none; } }`. ### Як браузер це обробляє Браузери парсять весь CSS наперед. Під час рендерингу рушій (Blink у Chrome, Gecko у Firefox) перевіряє кожну медіа-характеристику відносно поточного viewport через `window.matchMedia()`. При зміні розміру вікна відповідні набори правил активуються миттєво. Жодного перезавантаження сторінки, жодного перерахунку для елементів поза активними правилами. ### Типові помилки **`width` замість `min-width` або `max-width`:** ```css /* Неправильно: спрацює лише на точно 768px */ @media (width: 768px) { ... } /* Правильно: спрацює для 768px і менше */ @media (max-width: 768px) { ... } ``` **Desktop-first база з мобільним як другорядним:** ```css /* Неправильно: мобільний успадковує 3 колонки, якщо override відсутній */ .grid { grid-template-columns: repeat(3, 1fr); } @media (max-width: 768px) { .grid { grid-template-columns: 1fr; } } /* Правильно: mobile-first, складніші стилі додаються для ширших екранів */ .grid { grid-template-columns: 1fr; } @media (min-width: 769px) { .grid { grid-template-columns: repeat(3, 1fr); } } ``` **Вкладені медіа-запити** (одна з найпоширеніших CSS-помилок на Stack Overflow): ```css /* Неправильно: браузер повністю ігнорує внутрішній запит */ @media (max-width: 768px) { .parent { @media (max-width: 480px) { .child {} } } } /* Правильно: обидва запити окремо */ @media (max-width: 480px) { .child {} } ``` Я бачив, як розробники годинами шукали причину, чому макет ламається на телефоні, і зрештою виявляли, що вкладений запит просто ігнорувався весь цей час. ### Де зустрічається в реальних проектах - Tailwind CSS: брейкпоінти `md:` генерують `@media (min-width: 768px)` автоматично. - Bootstrap 5: використовує `@media (min-width: 576px)` для налаштування ширини `.container`. - React-застосунки: `@media (max-width: 1024px) { .menu-toggle { display: block; } }` для бургер-меню. - Next.js 14: глобальний CSS з медіа-запитами для адаптивного макету на рівні сторінки. ### Питання на співбесіді **Q:** У чому різниця між `@media (max-width: 768px)` і viewport-одиницями типу `vw`? **A:** `max-width` перемикає цілі набори правил на конкретному брейкпоінті. `vw` масштабує одну властивість безперервно, наприклад `font-size: 5vw`. Медіа-запити дають дискретні зміни макету, viewport-одиниці дають плавне масштабування. **Q:** Як реалізувати темну тему через CSS? **A:** `@media (prefers-color-scheme: dark) { body { background: #000; color: #fff; } }`. Браузер зчитує налаштування OS і застосовує стилі автоматично, JavaScript не потрібен. **Q:** Що таке container queries і чим вони відрізняються від media queries? **A:** Медіа-запити реагують на розмір viewport. Container queries (`@container`) реагують на розмір батьківського елемента, що робить компоненти перевикористовуваними незалежно від місця розміщення. Підтримуються в Chrome 105+ і Firefox 110+. **Q:** Як дебажити медіа-запит, що не спрацьовує в iOS Safari? **A:** Спочатку перевір viewport meta-тег: `<meta name="viewport" content="width=device-width, initial-scale=1">`. Без нього iOS рендерить у десктопному масштабі і брейкпоінти поводяться непередбачувано. Також перевір `-webkit-` префікси для специфічних властивостей. ## Приклади ### Базовий: відступи залежно від розміру екрану ```css .hero { padding: 100px 40px; /* десктоп: багато повітря */ } @media (max-width: 768px) { .hero { padding: 20px 10px; /* мобільний: компактно */ } } ``` На 1920px моніторі отримуємо 100px відступ зверху і знизу. На iPhone 375px він падає до 20px. Той самий елемент, дві поведінки, нуль JavaScript. ### Колапс навігації на планшеті і мобільному ```css .nav-bar { display: flex; justify-content: space-between; /* горизонтально на десктопі */ } .menu-toggle { display: none; /* бургер схований на десктопі */ } @media (max-width: 1024px) { .nav-bar { flex-direction: column; /* стекається вертикально для менших екранів */ } .menu-toggle { display: block; /* з'являється іконка бургера */ } } ``` Цей патерн є в кожному продакшн-застосунку з адаптивною навігацією. Кнопка-бургер з'являється лише тоді, коли екран занадто вузький для горизонтальної панелі. CSS повністю контролює зміну макету.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.