Как использовать Media Queries в JavaScript

Вольный перевод статьи «How to use Media Queries in JavaScript«. Автор Craig Buckler.

Это обновленная версия статьи, которая была опубликована 12 октября 2011 г. Что изменилось: обновлена информация, добавлено изображение, добавлено CodePen демо.

Отзывчивый дизайн (ориг.: Responsive design) является одним из самых крутых концептов разметки веб страницы с тех пор как CSS пришел на смену разметке таблицами. Данная технология использует медиа выражения (ориг.: media queries) для определения параметров устройства, на котором просматривается сайт в данный момент, с целью предоставления различных стилей в зависимости от параметров устройства. Вот эти параметры:

  • тип устройства
  • ширина экрана
  • высота экрана
  • ориентация экрана
  • разрешение экрана
  • отношение ширины экрана к высоте
  • глубина цвета

В следующем примере cssbasic.css будет загружено на все устройства, но если ширина экрана устройства больше 500 пикселей, дополнительно будет загружен csswide.css.

<link rel="stylesheet" media="all" href="cssbasic.css" /> 
<link rel="stylesheet" media="(min-width: 500px)" href="csswide.css" />

С таким подходом возможности бесконечны и эта техника использовалась очень многими сайтами. Если вы измените ширину экрана (растянете окно браузера например), то будет инициировано изменение разметки страницы. Т.е. ширина была меньше 500 пикселей применялись стили только из cssbasic.css, как только вы увеличили ширину и она стала больше 500 пикселей, в дополнение к предыдущим стилям начинают применяться стили из csswide.css.

Благодаря media queries сейчас можно легко адаптировать дизайн или изменять размеры элементов с помощью CSS. Но что, если нужно изменить контент или функциональность? Например на маленьких экранах вы хотите использовать более короткие заголовки, дополнительные JS библиотеки или изменить функциональность некоторых компонентов.

В принципе мы можем определить размер вьюпорта устройства с помощью JS, но выглядит это немного неаккуратно и запутано:

  • Большинство браузеров поддерживают window.innerWidth и window.innerHeight
  • window.onresize
  • Все основные браузеры поддерживают document.documentElement.clientWidth и document.documentElement.clientHeight, но значения этих свойств могут отличаться в разных браузерах, что делает этот подход не очень надежным.

Даже если удалось правильно определить размеры вьюпорта, все еще нужно самостоятельно вычислять ориентацию и отношения ширины экрана к высоте. Нет никакой гарантии, что то, что рассчитано вами будет совпадать с рассчитанными браузером показателями в случае применения им медиа выражений.

Как писать медиа выражения с помощью JavaScript.

К счастью сейчас возможно реагировать на изменение состояния медиа выражений с помощью JS. Основное API в данном случае — это window.matchMedia. Нужно передать строку медиа выражения идентичную той, которая используется в CSS медиа выражениях:

const mq = window.matchMedia( "(min-width: 500px)" );

Свойство matches возвращает true или false в зависимости от результата запроса, например:

Также можно объявить обработчик события, который будет вызван в случае обнаружения изменений в ширине например:

Также, после того, как был добавлен слушатель события, нужно вызвать обработчик события вручную для того, чтобы быть точно уверенным, что код, который опирается на размеры вьюпорта, будет инициализирован и отработает корректно. Без этого WidthChange() может быть никогда не вызван, если пользователь не менял размеры окна браузера.

На тот момент, когда пишется эта статья, matchMedia имеет очень широкую поддержку в браузерах. Т.е. нет причин не использовать это в продакшене.

Взгляните как динамически меняется отображение текста в примере ниже, если изменить ширину вьюпорта до значений меньших 500 пикселей.


Originally published at muntianblog.wordpress.com on August 5, 2017.