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

Kate

Administrator
Команда форума
*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, чтобы показать минимальную версию компонента на мобильном устройстве по сравнению с десктопом.

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

3c03251db5e403c3f4de132fd8fcf407.png

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

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

f18e18ec9e40aca2b69b6af53328ddd0.png

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

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

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

97a3043e4aa933be9510271a66c87011.png

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

86bb6f2cc2df48f5095c4ce9a6cc6f3b.png

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

86b49497b8e0b5e342c86532c737ab87.png

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

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

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

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

74f321659cc5b448a7867a4e11566102.png

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

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

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

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

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

832dd3dbf6508640a0ed28a9affc152b.png

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

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

8783bf4cf103c2d96941f537860e5c00.png

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

1d74b5cb8acb6f4cdef503eac0cec428.png

Видео по ссылке: 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 сетка).

217f420f651d417b53a33bb622d502a0.png

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

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



24ab9be41718e3f749ecd8dd1e8409f3.png

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

20878be2ffd494a3155e3a1e2b60fc83.png

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

57f02e9ec8c7ba8a0071a7eb6465c54f.png

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

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

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

e08dda0942d72832aea3d8ef0935ec46.png

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

2fd045449cf212b68c0b2beb91ae4495.png
0496bf47e235fc981361c7d34b85766b.png

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

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

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

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

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

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

a624ddacbc5d3cd48dacfaede0d1d025.png

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

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

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

  • Скрыть определенные элементы
  • Сделать кнопку во всю ширину
31386bdec19bd4fdff6c713f1f6a2d48.png

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

e45bdd92a14549af31d7080422969bed.png

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

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

Пагинация​

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

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

3a9062390b1487779ab5ebe5f1560443.png

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

cf9d64bcbba53acec27b1a20516881b1.png

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



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

84d3e1a5b054ac0e88c8545505762250.png

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

8186f6983c350930172e817cd11402d9.png

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

72cb5937b249c51bc3960bb8ceb56f5c.png

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

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

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

00e1378209a162c5d90888e6959caa72.png

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

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

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

d3254d363d8aa701de6e03b928da1c09.png

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

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

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

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

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

Заключение​

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

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

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

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

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

f2bb129ae23cf837319bf647b7e398f9.png

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

Источник статьи: https://habr.com/ru/company/otus/blog/557000/
 
Сверху