Знакомство с CSS Container Queries
В этом курсе мы познакомимся с выражениями от контейнера, также известными как CSS Container Queries
. Они позволяют в зависимости от параметров контейнера изменять отображение как самого контейнера, так и его дочерних элементов.
Представьте, что вам нужно создать небольшой чат, который может располагаться в правой узкой или нижней широкой части экрана. При этом он должен выглядеть хорошо в обоих местах.
Размер экрана остается неизменным для разного расположения чата, поэтому media queries
здесь не помогут. А выражения от контейнера помогут решить эту задачу. Давайте вместе создадим такой чат.
Начнём разметки.
Создадим раздел (<section>
) для всего блока чата, а точнее для всего контейнера.
Добавим заголовок, который скоро доступно скроем. Добавим логотип компании, с которой будем общаться.
Добавим сообщения.
Зададим контейнеру минимальную и максимальную ширину, поля и отступы. Определим цвета. За счёт автоматических отступов по горизонтали разместим контейнер по центру.
Сообщения располагаются друг под другом сверху вниз. Для сетки используем флекс, чтобы с помощью CSS-свойства gap
установить отступы между сообщениями.
Для улучшения внешнего вида скруглим углы логотипа и выровняем его по центру.
Начнём стилизовать сообщения.
Добавим дополнительные классы, чтобы по-разному стилизовать входящие и исходящие сообщения.
Зададим разные стили для входящих и исходящих сообщений.
Зададим общие стили сообщений: скругление, отступы и размер.
Добавим адаптивность чату за счёт выражения от контейнера. Но сначала немного теории.
В выражении от контейнера есть три основных конструкции:
- CSS-свойство
container-type
добавляет элементу «containment context» и
описывает, какую размерность контейнера можно использовать при выполнении контейнерных запросов. - CSS-свойство
container-name
позволяет при желании присвоить контейнеру имя. - Директива
@container
используется для создания контейнерных запросов.
С помощью container-type
элементу добавляется «containment context». Затем в @container
создаются к нему запросы.
CSS-свойство container-type
может принимать несколько значений:
inline-size
позволяет использовать ширину контейнера в медиа-запросах;size
позволяет использовать как ширину, так и высоту контейнера в запросах;normal
— значение по умолчанию, при котором элемент не участвует в контейнерных запросах по размеру, но может использоваться в стилевых запросах (это значение нам сейчас не понадобится, рассмотрим его позже).
Укажем container-type: inline-size
для .chat
. После этого у элемента появится «containment context» (устоявшегося перевода термина пока нет). А дальше можно создавать запросы.
Обратите внимание, что контейнер .chat
начал ужиматься под контент после того, как мы установили ему container-type: inline-size
. Это нормальное поведение элементов, которым добавлен «containment context», и нужно помнить о нём при вёрстке.
Создадим пустой запрос от контейнера с помощью директивы @container
.
Укажем условие: если размер контейнера меньше 500px
, то измени стили
.
Правда ведь похоже на медиавыражения?
В этом шаге мы полностью отказались от размеров от вьюпорта (экрана браузера).
Для всех элементов внутри запроса браузер ищет ближайшего предка, у которого добавлен «containment context». Блоки .message
находятся внутри .chat
, у которого есть «containment context», поэтому запрос сработает для них.
Изменим стили сообщений, которые находятся внутри контейнера с шириной меньше 500px
. Пусть они выравниваются по центру и растягиваются на всю возможную ширину.
Чтобы убедиться, что выражения от контейнера работают, временно добавим для .chat
CSS-свойства resize: horizontal;
и overflow: hidden;
. В правом нижнем углу блока появится область, которую можно тянуть влево или вправо, чтобы изменить его ширину.
Попробуйте уменьшить или увеличить ширину блока и посмотрите, как ведут себя сообщения.
Теперь разберёмся с container-name
. Это свойство позволяет именовать контейнер, а затем создавать запросы с именем контейнера.
Именуем контейнер с помощью container-name
. Укажем ему имя chat
.
Если контейнеру задано имя, его можно использовать в директиве @conainer
.
Именование контейнера полезно в крупных проектах, в которых могут быть десятки контейнеров.
Вместо отдельных CSS-свойств:
container-type: inline-size;
container-name: chat;
Можно использовать сокращённое CSS-свойство:
container: chat / inline-size;
На этом знакомство с выражениями от контейнера завершено.