От автора: все мы слышали про медиа запросы в CSS, с помощью которых можно изменять внешний вид элемента на основе ширины экрана. Элементные запросы похожи на медиа запросы, но условия адаптивности применяются к отдельным элементам на странице, а не к вьюпорту. Например, можно применять различные стили к элементу на основе его собственной ширины, количества элементов внутри него или того, каким образом пользователь прокрутил страницу.
Зачем нам нужны элементные запросы?
В начале я уже сказал, что элементные запросы помогают стилизовать элементы по ряду свойств, а не просто по ширине и высоте вьюпорта. Помимо этого существует еще несколько ситуаций, когда библиотека может оказаться крайне полезной.
Например, вы создали красивый адаптивный макет, на котором все элементы идеально подходят друг к другу. И вас попросили добавить к колонкам еще одну. Пространства для всех остальных колонок станет меньше.
Ваши изображения и текст с идеальными пропорциями для колонок шириной 800px на вьюпорте шириной 1366px могут не так хорошо смотреться в колонках шириной 600px на том же вьюпорте. Ширина вьюпорта осталась прежней, а вот колонки стали уже, чтобы освободить место под сайдбар. Использование элементных запросов вместо медиа запросов в таких ситуациях может сэкономить вам кучу времени, потому что вам не придется переписывать CSS при любых изменениях в макете.
В демо ниже если наш вьюпорт сужается (становится уже 500px), мы задаем изображениям ширину 100% и перемещаем все в одну колонку. Однако на большом вьюпорте если кликнуть на кнопку «Add Sidebar», основная колонка станет значительно уже без изменения ширины вьюпорта, из-за чего изображение кажется слишком маленьким.
Теперь давайте представим, что вы создаете виджет или плагин, а для адаптивности используете медиа запросы. Проблема заключается в том, что виджет может быть внутри контейнера, чья ширина равна вьюпорту или одной четвертой. Если ширина виджета зависит от ширины контейнера, то нельзя полагаться на размер вьюпорта для стилизации виджета, это не сработает. Здесь нам помогут элементные запросы! Элементные запросы сработают как надо, так как они используют собственную ширину виджета для стилизации.
На изображении ниже один виджет помещен в два разных места. Как видите, ширина вьюпорта одинаковая, а ширина виджетов разная. Так как стили применяются на основе ширины виджета, то оба виджета идеально вписались в макет.
Элементные запросы отделяют условия адаптивности от макета страницы. Можно создавать и стилизовать компоненты типа меню и таблиц без оглядки на окружающие элементы. То есть таблицу с ценами для сайта А можно использовать на сайте B. Сильно помогает при создании шаблонов.
Начинаем работу с EQCSS
Чтобы использовать элементные запросы в своих проектах, вам понадобится подключить EQCSS в HTML. Скачать файл можно с их репозитория на GitHub или по прямой ссылке на минифицированный файл на CDNjs.
Плагин поддерживает все современные браузеры, в том числе IE9 и выше. Если вам нужно поддерживать IE8, вам также понадобится подключить полифил в свой проект. Полифил должен быть подключен перед плагином.
1 2 3 4 |
<!‐‐[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/eqcss/1.4.0/EQCSS-polyfills.min.js"></script> <![endif]‐‐> <script src="//cdnjs.cloudflare.com/ajax/libs/eqcss/1.4.0/EQCSS.min.js"></script> |
После подключения нужных файлов, можно начать использовать EQCSS в своих проектах. Существует два способа. Самый простой – просто писать EQCSS в обычном CSS в тегах style или link. Другой способ – отдельно подключать EQCSS стили внутри тега script с пользовательским типом:
1 2 3 4 5 6 7 |
<script type=text/eqcss> /* Вставьте ваш EQCSS */ </script> или <script type="text/eqcss" src="path/to/styles.eqcss"></script> |
По умолчанию скрипт будет выполняться и вычислять все стили после загрузки контента, а также по событиям resize и scroll. Начиная с версии 1.2, плагин также срабатывает на события input, click, mouseup и mousemove. Для событий scroll если запрос применен к body или html, событие прокрутки цепляется к window. В остальных случаях событие прокрутки цепляется к элементу, заданному в запросе.
Если нужно заново вычислить стили по какому-то другому событию, можно вызвать EQCSS.apply().
Пишем элементные запросы
Синтаксис элементных запросов сильно напоминает медиа запросы. Например, элементный запрос начинается с @element, после чего идет хотя бы один селектор, к которому будут применяться стили.
1 2 3 |
@element {selector} and {condition} { /* Ваш валидный CSS */ } |
Изображение в демо выше, может полностью заполнять ширину контейнера с помощью следующего запроса:
1 2 3 4 5 |
@element ".content" and (max-width: 480px) { .content img { width: 100%; } } |
Как только ширина нашего контента станет меньше 480px, все изображения внутри контейнера получат ширину 100%. Только есть одна проблема. EQCSS повторно вычисляет стили только при изменении размера окна браузера, по событию click или scroll. В нашем случае нам нужно вызывать EQCSS.apply() в событии click по кнопке. В демо ниже показано, как хорошо наше изображение адаптируется к дополнительной колонке (если ширина окна больше 480px, вам нужно уменьшить ширину окна браузера):
Условия в элементных запросах не ограничиваются шириной и высотой элемента. Элементы можно стилизовать по количеству дочерних элементов. Один из примеров, что приходит на ум – карточный макет на домашней странице сайта SitePoint. Все карточки в разделе Избранное имеют одну ширину и высоту, а вот длина заголовка в карточке может быть разной. Когда заголовок слишком длинный и не вмещается в карточку, можно уменьшить размер шрифта с помощью EQCSS:
1 2 3 4 5 |
@element ".card h2" and (min-characters: 50) { $this { font-size: 1em; } } |
Некоторые из вас могли заметить, что я использовал $this вместо .card h2. Если использовать .card h2, то размер шрифта изменится во всех заголовках в карточках, а конструкция $this изменит шрифт только в заголовке, чья длина превышает заданный лимит. Есть и другие схожие селекторы: $parent , $prev и $next. Все эти селекторы называют мета селекторами.
Использование элементных запросов
Прежде чем решить, давать ли элементным запросам шанс, читатели SitePoint, возможно, хотят узнать, как на самом деле работает плагин, чтобы определить, подходит ли это решение под их проекты (и понять, как нельзя его использовать). Ниже я описал, что происходит за кулисами:
В цикле прогоняются все элементные запросы и находятся необходимые элементы. Далее в цикле прогоняются найденные элементы, всем им назначается уникальный идентификатор в форме атрибута. Формат идентификатора data-eqcss-{element-query-index}-{matched-element-index}. Data-атрибут добавляется к родительскому элементу, который получается путем добавления –parent к идентификатору элемента. Похожие идентификаторы добавляются к предыдущему и следующему смежному элементу. В конце все элементы и их запросы проверяются на выполнение всех возможных условий, таких как min-height, max-height, min-scroll-x и т.д., после чего применяются стили.
Стили добавляются в тег
. Принудительная задержка обеспечивает вызов EQCSS.apply() не чаще 200ms (задержка по умолчанию). В отличие от resize, input и click, события scroll срабатывают только на элементах, использующих элементный запрос scroll.Стили для разных элементов вычисляются с помощью JS, то есть производительность зависит от количества элементов, к которым применяются стили. В Firefox и Edge наблюдаются заметные лаги при большом количестве элементов. В последней версии Firefox производительность была улучшена, а в будущем она будет еще лучше.
В идеале, плагин должен добавлять один или два EQCSS data-атрибута на элемент. Если ошибиться, то на один элемент могут быть присвоены десятки EQCSS атрибутов, что сильно засоряет разметку. Вы же не хотите, чтобы ваша разметка стала похожа на:
Также не забывайте, что не нужно добавлять все эти атрибуты в HTML вручную. Они вставляются автоматически в момент работы плагина.
Отладка элементных запросов немного сложнее медиа запросов. На данный момент браузеры отличают только медиа запросы, про элементные запросы они не знают. Поэтому они смогут разобрать только стили EQCSS.
После прочтения статьи вы можете захотеть заменить все медиа запросы на элементные запросы. Не делайте этого. Во-первых, медиа запросы запускаются быстрее элементных, так как последние полагаются на JS для вычисления стилей. Слишком много элементных запросов могут убить производительность вашего сайта (в Firefox и IE).
В 2015 плагин плавно работал в Firefox. Однако в начале 2016 разработчики внесли пару изменений в браузер, из-за чего производительность упала. Разработчикам плагина пришлось принудительно занижать частоту вызова с помощью EQCSS.throttle() и контролировать повторную сборку стилей.
Во-вторых, медиа запросы используются не только для стилизации элементов на экране. Их также используют для создания стилей для других медиа типов и свойств. В качестве примера – стили для версии страницы для печати все еще добавляются через медиа запросы.
Заключение
EQCSS замечательный инструмент, если правильно подойти к делу. С помощью этого плагина можно делать много всего, что невозможно в медиа запросах. При большом количестве элементов может пострадать производительность, однако синтаксис элементных запросов очень похож на медиа запросы. Изучение не будет трудным.
В будущем браузеры могут получить такие функции, как ResizeObserver, с помощью которых разработчики смогут создавать улучшенные плагины для условий min-width, max-width, min-height и max-height. Появится поддержка Houdini, которая позволит добавлять поддержку этих условий прямо в браузер. Разработчики будут работать над создание плагина, который вберет в себя все эти функции, но они также планируют продолжить поддерживать текущий плагин EQCSS. Их цель – разработать семейство плагинов, чтобы каждый из них подходил под определенный браузер.
А что вы думаете об этой библиотеке? Использовали ее уже в своих проектах? Пишите в комментариях.
Автор: Baljeet Rathi
Источник: //www.sitepoint.com/
Редакция: Команда webformyself.