Приветствуем CSS Container Queries

Автор оригинала: Ahmad Shadeed
  • Перевод

*Container Queries — Выражения от контейнера 

За последние шесть лет моей работы в качестве front-end разработчика я не был так рад появлению CSS фитчи, как сейчас. Прототип container queries теперь доступен в Chrome Canary. Благодаря усилиям таких умных людей, как Miriam Suzanne и других.

Я помню, что видел много шуток по поводу поддержки CSS container queries, но они наконец-то появились. В этой статье я расскажу вам, зачем нужны container queries, как они облегчат вам жизнь, а главное, вы увидите более мощные компоненты и разметки.

Если вы взволнованы так же, как и я, то давайте начнем. Вы готовы?

Проблема с CSS Media Queries

*CSS Media Queries - Медиа запросы

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

Зачастую отзывчивый веб-дизайн не имеет отношения к области просмотра или размеру экрана. Речь идет о размере контейнера. Рассмотрим следующий пример:

У нас есть очень типичная разметка компонента карточки, которая имеет две вариации:

  • Cтековая (см. в сторону)

  • Горизонтальная (см. основную)

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

Обратите внимание, что мы создали класс .c-article--horizontal для работы с горизонтальной версией компонента. Если ширина области просмотра больше 46rem, то компонент должен перейти в горизонтальную вариацию.

Это не плохо, но почему-то это заставляет меня чувствовать себя немного ограниченным. Я хочу, чтобы компонент реагировал на ширину родительского компонента, а не на область просмотра браузера или размер экрана.

Предположим, что мы хотим использовать стандартную .c-card в главной секции. Что произойдет? По сути, карточка расширится до ширины родительского компонента и, таким образом, будет слишком большой. Смотрите следующий рисунок:

Это проблема, и мы можем решить ее с помощью CSS container queries (ура, наконец-то). Однако, прежде чем погрузиться в них, позвольте мне дать вам представление о результате, который мы хотим получить.

Нам нужно указать компоненту, что если ширина его родительского компонента больше 400px, то он должен переходить на горизонтальный стиль. Вот как будет выглядеть CSS:

Как CSS Container Queries помогают нам?

Внимание: CSS container queries пока поддерживаются только в Chrome Canary под экспериментальным флагом.

С помощью CSS container queries мы можем решить вышеописанную проблему и сделать компонент Fluid. Это значит, что мы можем поместить компонент в родительский, и он превратится в сложенную версию, или поместить его в широкий компонент, и он превратится в горизонтальную версию. Опять же, все это не зависит от ширины области просмотра.

Вот как я себе это представляю.

Фиолетовый контур представляет собой ширину родительского компонента. Обратите внимание, что когда происходит увеличение, компонент адаптируется к этому. Разве это не потрясающе? В этом и заключается сила CSS container queries.

Как работают Container Queries?

Теперь мы можем поэкспериментировать с Chrome Canary container queries . Чтобы активировать их, перейдите по адресу chrome://flags  и найдите "container queries", а затем запустите их.

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

Значение inline-size означает, что нужно реагировать только на изменение ширины родительского компонента. Я пробовал использовать block-size, но это пока не работает. Пожалуйста, поправьте меня, если я ошибаюсь.

Это первый шаг. Мы определили элемент .o-grid__item в качестве родительского элемента для содержащегося в нем .c-article.

Следующим шагом будет добавление стилей, необходимых для работы container queries.

@container - это элемент .o-grid__item, а min-width: 400px- его ширина. Мы можем даже пойти дальше и добавить больше стилей. Вот видео о том, чего можно добиться для компонента карточки:

Видео по ссылке: https://ishadeed.com/assets/cq/cq-1.mp4

Здесь есть следующие стили:

  • По умолчанию - вид, похожий на карточку.

  • Горизонтальная карточка с небольшой миниатюрой.

  • Горизонтальная карточка с большой миниатюрой.

  • Если родительский компонент слишком большой, то это будет как hero-стиль с указанием на то, что это тематическая статья.

Давайте разберемся с вариантами использования CSS container queries.

Использование кейсов для CSS Container Queries

Container Queries и CSS Grid auto-fit

В некоторых случаях использование auto-fit в CSS grid может привести к неожиданным результатам. Например, компонент будет слишком широким, и его содержимое будет трудно прочитать.

Чтобы немного прояснить ситуацию, вот наглядный пример, показывающий разницу между auto-fit и auto-fill в CSS grid (CSS сетка).

Обратите внимание, что при использовании auto-fit элементы расширяются, заполняя доступное пространство. Однако в случае auto-fill элементы сетки не будут увеличиваться, и вместо них появится свободное пространство (пунктирный элемент в крайнем правом углу).

Возможно, вы сейчас подумаете, какое отношение это имеет к CSS container queries? Так вот, каждый элемент сетки является контейнером, и когда он расширяется ( когда мы используем auto-fit), нам нужно, чтобы компонент менялся соответственно.


Когда у нас будет четыре элемента, результат должен выглядеть примерно так.

Это изменится, когда количество статей станет меньше, смотрите, что произойдет. Чем меньше статей, тем шире они становятся. Причина в том, что используется auto-fit. Первый вариант выглядит хорошо, но последние два (2 в ряду, 1 в ряду) выглядят не очень хорошо, так как они слишком широкие.

Что если каждый компонент статьи будет изменяться в зависимости от ширины его родительского компонента? Таким образом, мы сможем получить преимущество auto-fit. Вот что нам нужно сделать:

Если ширина элемента сетки больше 400px, то статья должна переходить на горизонтальный стиль.

Вот как мы можем это сделать:

Кроме того, мы хотим отображать статью с hero-секцией, если это единственный элемент в сетке.

Вот и все. У нас есть компонент, который реагирует на ширину своего родительского компонента, и он может работать в любом контексте. Разве это не потрясающе?

Посмотрите демо-версию на CodePen.

Боковая и основная панель

*Сайдбар - боковая панель

Зачастую нам нужно настроить компонент так, чтобы он работал в контейнерах небольшой ширины, например как <aside>.

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

Как вы видите на рисунке, у нас есть новостная лента, которая находится в двух разных контекстах:

  • Боковой панели

  • Основной панели

Без container queries невозможно ничего сделать, пока у нас не появится класс вариаций в CSS, например, .newsletter--stacked или что-то подобное.

Я знаю, что мы можем заставить элементы свернуться в случае недостатка места с помощью flexbox, но этого недостаточно. Мне нужно гораздо больше контроля, чтобы:

  • Скрыть определенные элементы

  • Сделать кнопку во всю ширину

Вот видео с результатом.

Ссылка на видео: https://ishadeed.com/assets/cq/use-case-newsletter.mp4

Посмотрите демо-версию на CodePen.

Пагинация

Я обнаружил, что пагинация хорошо подходит для использования container queries. Изначально мы можем использовать кнопки "Предыдущий" и "Следующий", затем мы можем скрыть их и продемонстрировать полную пагинацию, если у нас достаточно места.

Взгляните на следующий рисунок.

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

Посмотрите демо-версию на CodePen.


Карточка профиля

Вот еще один пример, который идеально подходит для использования в нескольких контекстах. В зависимости от состояния, оно может подходить для небольшой области просмотра и таких контекстов, как боковая панель или для более крупных контекстов, например, для размещения в 2-col сетке.

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

Посмотрите демо-версию на CodePen.

Формирование элементов

Я пока не углублялся в использование форм, но один из вариантов, который у меня на уме, - это переход от горизонтального расположения меток к сложенному.

Попробуйте сами в демо-версии ниже. Просмотрите демо-версию на CodePen.

Тестирование компонентов

Теперь, когда мы рассмотрели несколько случаев использования CSS container queries, как мы можем протестировать компонент? К счастью, мы можем сделать это с помощью свойства CSS resize родительского компонента.

Я узнал об этой технике, прочитав эту замечательную статью Bramus Van Damme.

Легко ли дебаггить сontainer queries в DevTools?

Короткий ответ - нет. Вы не можете увидеть что-то вроде @container (min-width: value). Я думаю, что это вопрос времени, и это будет поддерживаться.

Можно ли предусмотреть запасной вариант?

Да! Конечно. Определенными способами можно обеспечить возврат. Вот две замечательные статьи, которые объясняют, как это сделать:

Заключение

Мне понравилось узнавать о CSS container queries и экспериментировать с ними в браузере. Я знаю, что они еще официально не поддерживаются, но сейчас самое время поработать с ними в браузере.

Так как мы front-end разработчики, часть нашей работы заключается в тестировании и помощи тем, кто работает над внедрением таких функций. Чем больше мы тестируем, тем меньше проблем мы увидим, когда это будет поддерживаться во всех основных браузерах.

Спасибо, что прочитали.

Я написал электронную книгу

Я рад сообщить вам, что написал электронную книгу о дебаггинге CSS.

Если вам интересно, зайдите на сайт debuggingcss.com для бесплатного предварительного просмотра...


В преддверии старта курса "HTML/CSS" приглашаем всех желающих на бесплатный демо-урок «CSS Reset — ненужный артефакт или спасательный круг». На этом вебинаре рассмотрим, зачем нам CSS Reset, что такое рендеринг и как браузер рендерит страницу.

OTUS
Цифровые навыки от ведущих экспертов

Комментарии 3

    0

    Вещь нужная. Осталось теперь добавить единицы измерения lw, lh и lmin, аналоги vw, vh, vmin, чтобы плавно адаптивить font-size.

      0
        0

        Дубликат.

        Перевод появился на Хабре 2 недели назад: https://habr.com/ru/company/skillfactory/blog/554434/

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое