Перевод статьи eqio — A simple, tiny alternative to element/container queries с сайта medium.com для css-live.ru, автор — Мэтт Стоу
Классические принципы отзывчивого дизайна больше не отвечают нашим, разработчиков дизайн-систем и библиотек компонентов для веба, потребностям. Если уж с этим согласен Итан Маркотт, основоположник понятия «отзывчивый дизайн», то наверняка это правда.
Когда мы делим наши компоненты на отдельные многоразовые частички с помощью React и Vue, и аналогично строим CSS-архитектуру, чтобы она подходила классам с ограниченной областью видимости или библиотекам CSS-in-JS, всё прекрасно… но лишь до поры. Когда надо использовать компонент совсем не в том контексте, для которого он создавался, или компонент регулярно меняется на какие-то заклинания и обратно, едва он меняет размер, нет смысла соотносить эти изменения с произвольным размером окна браузера, от этого только масса лишнего CSS.
Как бы ни надеялся я однажды увидеть нативные выражения от контейнера (Container Queries) наяву, я не могу просто ждать; мне они нужны сейчас. Хотя уже есть немало попыток «заполифилить» поведение выражений от контейнера, все они меня чем-то не устраивали, так что я решил сделать свою!
У eqio «под капотом» механизм IntersectionObserver (который хорошо поддерживается в «хороших» браузерах и легко полифилится в остальным), чтобы компоненты могли адаптировать свои стили, исходя из своей ширины (а не окна браузера), для чего к ним применяются классы с подходящим именем, когда их ширина соответствует заранее заданным условиям.
Хотя eqio не охватывает всех возможных применений для выражений от контейнера, она поддерживает два важнейших: подстройку на основе минимальной ширины компонента, а также адаптацию под его максимальную ширину.
Давайте взглянем на пример:
See the Pen eqio — простые выражения от элемента с IntersectionObserver by Ilya Streltsyn (@SelenIT) on CodePen.
Библиотечка eqio должна легко встраиваться в любой проект минимумом кода:
HTML
- Добавить элементу класс
eqio
. - Добавить атрибут
data-eqio-sizes
, значение которого — массив размеров в виде JSON-строки. - Если нужно, добавить атрибут
data-eqio-prefix
, значение которого будет служить префиксом для ваших названий классов.
<div class="media-object eqio" data-eqio-sizes='["<400", ">700"]' data-eqio-prefix="media-object" > … </div>
Показанный выше компонент будет:
- иметь возможность особого оформления, когда его ширина 400 или меньше (
"<"
— синоним дляmax-width
, а не «менее чем»). - иметь возможность особого оформления, когда его ширина 700 или больше (
">"
— синоним дляmin-width
, а не «более чем»). - применять классы
media-object-eqio-<400
иmedia-object-eqio->700
, когда надо. Если не указать атрибутаdata-eqio-prefix
, будут применяться классыeqio-<400
иeqio->700
.
Примечание: могут применяться сразу несколько классов.
CSS
В CSS записывайте имена классов, совпадающие с теми, что применяются в HTML.
.media-object-eqio-\<400 { /* специальное оформление при 400px и менее */ } .media-object-eqio-\>700 { /* специальное оформление при 700px и более */ }
Примечание:
- классы eqio содержат спецсимволы
<
и>
, поэтому в CSS их нужно экранировать символом\
. - у элементов с eqio по умолчанию стоит
position: relative
, но можно переопределить это для вашего компонента наabsolute
/fixed
и т.д., если нужно. - у элементов с eqio не может быть других значений
overflow
, кромеvisible
.
JavaScript
Если используете сборщик модулей, вроде webpack, первым делом подключите Eqio
импортом.
import Eqio from 'eqio';
В своем JS-коде укажите, какие элементы eqio сделает отзывчивыми, передав в Eqio
ссылку на DOM.
var mediaObject = new Eqio(document.querySelector('.media-object'));
Если элемент больше не должен быть отзывчивым, можно вызвать .stop()
для этого экземпляра:
mediaObject.stop();
Это уберет все Observer-ы и внутренности equio, кроме имен классов, которые были в тот момент назначены.
Довольно легко, правда?
Хотя я не сомневаюсь в возможностях eqio, до тех пор, пока не появятся «родные» выражения от контейнера, я всё же рекомендовал бы использовать JavaScript-альтернативы как улучшение, а не как обязательное требование в верстке.
С этой целью старайтесь отделять CSS, на котором строится интерфейс страницы, от стилей компонентов. Пускай макет страницы управляется медиавыражениями, флексбоксами и т.д., и добейтесь, чтобы компоненты изначально наилучшим образом отображались для большинства пользователей, улучшая отзывчивое поведение с помощью флексбоксов или CSS-гридов где можно, прежде чем хвататься за решение для выражений от контейнера.
В любом случае, больше информации и инструкции по установке — в репозитории eqio на GitHub. И, конечно, прошу поделиться со мной своими мыслями!
P.S. Это тоже может быть интересно: