Медіа-запити CSS, matchMedia та user-agent. Що і коли потрібно?
Google видає чимало статей на тему “Як зробити сайт адаптивним”, але тритина з них — написані більше для UX-UI-дизайнерів, ніж для фронтендерів. Ще тритина — SEO-вода про те, що адаптивність дуже важлива і обов’язково має бути. І лише в деяких можна нарешті дізнатись про медіа-запити CSS та як їх вживати.
Дисклаймер: я поки не знаю, яка тут збереться аудиторія. Для профі ця інформація можливо є очевидною, а для зовсім початківців — навпаки складною. Припустимо поки, що ви на тому рівні, коли вже адаптували невелички сторінки за допомогою CSS, і тепер стикнулися з необхідністю зробити адаптив білш функціонального проекту. Для мене свого часу було не очевидно, які ще інструменти, окрім медіа-запитів, фронтендер може використовувати аби створити притомний адаптив. Тому далі кілька способів, їх плюси та мінуси.
Медіа-запити
Медіа-запити на сьогодні є основним та найбільш зручним інструментом для того, щоб врахувати розміри екранів майбутніх користувачів сайту. Це функціонал вшитий в сам CSS, тому ви можете легко змінювати стилі залежно від розміру екрану і багатьох інших параметрів. Для простих веб-сторінок найчастіше цього способу вистачає з головою.
За допомогою медіа-запитів можна прописати стилі для будь яких розмірів, а також врахувати оріентацю:
Плюси:
Можливість змінювати CSS під всі розміри і орінтації.
Не треба використовувати JavaScript (менше коду — легший бандл).
Мінуси: впливає тільки на CSS, неможливо при зміні розміру екрану виконати код, якщо функціонал цього вимагає.
matchMedia
matchMedia — це JavaScript API, який дозволяє перевірити, чи задовольняють умови медіа-запиту контексту перегляду. Деталі дивіться на MDN. В сутності це метод, завдяки якому ми вже можемо хендлити зміни розмірів екрану користувача джаваскриптом: показувати (чи приховувати) контент, виконувати (або забороняти) певний функціонал.
matchMedia викликається в об’єкту Window і повертає нам MediaQueryList — все, що ми хочемо знати про поточний медіа-запит нашого юзера, і низку методів. Наприклад, ми передаємо matchMedia умову — “orientation: portrait” — і отримуємо matches (бульове значення, яке відповідає, чи орієнтація екрану портретна).
matchMedia містить не тільки буліан matches, а й методи, що допоможуть одразу обробити подію. Наприклад, onchange:
Плюси:
Зручний, зрозумілий, одним словом, бро.
Викликається один раз на сторінці і далі буде слідкувати за змінами екрану автоматично — функції-хендлери мають відпрацьовувати кожного разу, як подія (зміна розміру) настане.
Можна комбінувати з медіа-запитами. Наприклад, при стисканні вікна на десктопі спочатку можуть відпрацьовувати медіа-запити: зменшувати шрифт, ширину картинок та блоків. А при певному розмірі — matchMedia — щоб, припустимо, замінити стандартне меню на меню-бутерброд.
Мінуси:
В разі роботи з фреймворками можливо знадобиться додатковий код. На React, наприклад, я писала кастомний хук, що полегшує використання matchMedia.
User-Agent
User-Agent — це рядок з інформацією, яку браузер передає за допомогою HTTP на сервер сайту. User-Agent містить дані про власне клієнтський браузер, операційну систему, тип пристрою, розширення браузера та інше. Ми можемо отримати цей рядок, викликавши метод userAgent у властивості navigator:
Плюси:
Можливість відрізнити десктопні пристрої від телефонів і планшетів. Іноді це дуже важливо, бо планшети мають досить широкі екрани — медіа-запити для них відпрацюють як для десктопа, а це не завжди добре (наприклад при використанні тачпаду).
Адаптивність для конкретних (не стандартних) браузерів, якщо це потрібно. Припустимо ви знаєте, що деякі браузери не підтримують CSS Grid або Flexbox, тоді ви можете використати цю інформацію для налагодження оптимального відображення. За каденції Internet Explorer було актуально:))
Мінуси:
!!! Дані User-Agent бувають хибними, тому що користувачі можуть самотійно їх змінювати для конфіденційності, безпеки, заради прикола, тощо. Тому не слід використовувати тільки цей спосіб для створення адаптиву.
Отже для того, щоб зробити сайт адаптивним в разі простих проектів достатньо використовувати стандартні медіа-запити, а в білш складних випадках додавати matchMedia i User-Agent. У своїй роботі над адаптивністю я найчастіше використовую саме це. А як чините ви? Радо послухаю в коментарях.