eqio — простая, компактная альтернатива выражениям от элемента/контейнера

Перевод статьи 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

  1. Добавить элементу класс eqio.
  2. Добавить атрибут data-eqio-sizes, значение которого — массив размеров в виде JSON-строки.
  3. Если нужно, добавить атрибут 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. Это тоже может быть интересно: