От автора: несколько дней назад я увидел твит Мириам Сюзанн о поддержке единиц измерения запросов CSS. Первоначально это было предложено Уной Кравец на Github. Я не мог не поэкспериментировать с ними и посмотреть, как мы можем получить еще больше преимуществ от контейнерных запросов CSS.
Я постараюсь объяснить, как работает каждая из единиц, и где мы можем их использовать, чтобы улучшить реакцию компонента на ширину его родительского элемента.
Напоминание: контейнерные запросы CSS поддерживаются только в Chrome Canary. Чтобы поэкспериментировать с ним, перейдите в поисковой строке по адресу chrome://flags и включите функцию «Включить контейнерные запросы CSS».
Вступление
В CSS у нас есть много единиц измерения, которые можно использовать для разных целей. Наиболее используемые из них px, rem и em. Если есть что-то близкое к тому, как работают единицы контейнерных запросов CSS, я бы назвал единицы на основе области просмотра.
Единицы на основе области просмотра CSS работают таким образом, чтобы соответствовать размеру области просмотра браузера (ширине и / или высоте). Это здорово, но мы не всегда хотим использовать единицы измерения, связанные с размером области просмотра. Что, если мы хотим запросить ширину контейнера? Вот для чего нужны единицы запросов.
Чтобы было понятнее, я хочу выделить разницу между единицами области просмотра и единицами запроса. Рассмотрим следующий рисунок:
Слева, значение font-size изменяется rem и vw и будет относиться к ширине области просмотра. В некоторых случаях это может сработать, но может вызвать непредвиденные проблемы, поскольку оно зависит от размера области просмотра.
Единицы запросов могут сэкономить наши усилия и время , когда мы имеем дело с такими вещами, как font-size, padding и margin в компоненте. Вместо того, чтобы вручную увеличивать размер шрифта, мы можем использовать единицы запроса. Рассмотрим следующий пример.
У нас есть карточный компонент, который изначально имеет сложенный стиль, но когда контейнер большой – приобретает hero-стиль. Для такого компонента нам может потребоваться изменить следующие вещи:
Размер эскиза
Размер шрифта
Расстояние между элементами
Без единиц запроса CSS нам нужно вручную изменить вышеуказанное.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
.card { /* The stacked, base style */ } .card__title { font-size: 1rem; } /* The horizontal style, v1 */ @container (min-width: 400px) { .card__title { font-size: 1.15rem; } } /* The horizontal style, v2 */ @container (min-width: 600px) { .card__title { font-size: 1.25rem; } } /* The hero style */ @container (min-width: 800px) { .card__title { font-size: 2rem; } } |
Обратите внимание, как размер шрифта .card__title изменяется с различными контейнерными запросами. Мы можем улучшить это и избежать дублирования font-size, используя единицы запроса вместе с функцией CSS clamp().
1 2 3 |
.card__title { font-size: clamp(1rem, 3qw, 2rem); } |
При этом нам нужно определить font-size только один раз. Если мы хотим сравнить это визуально, вот как это выглядит:
Если вы знакомы с единицами просмотра CSS, это не будет для вас новостью. Похоже на запрос к контейнеру, а не к области просмотра браузера. Демо.
Единицы Запроса
Теперь, когда у нас есть представление о задачах, которые должны решать единицы запросов, давайте рассмотрим их. Согласно спецификации CSS:
Запрос ширины (qw): 1% ширины контейнера. Например, 5qw равно 5% ширины контейнера.
Запрос высоты (qh): 1% от высоты контейнера. Например, 5qh равно 5% высоты контейнера.
Запрос минимума (qmin): меньшее значение запроса ширины qw или запроса высоты qh.
Запрос максимума (qmax): большее значение qw или qh.
У нас также есть две друге единицы: qi и qb, они означают, соответственно, встроенный запрос и блок запроса.
Варианты использования и примеры
Компонент Карты
В дополнение к ранее объясненному примеру о карточках мы можем использовать единицы запроса для сложенной карточки, где мы хотим, чтобы размер шрифта был немного больше в зависимости от ширины контейнера.
Обратите внимание, что размер шрифта становится меньше, в зависимости от размера контейнера. Это может быть полезно для создания составного компонента карты, который работает независимо от того, где он размещен. Демо.
Изменение font-size в зависимости от важности
Когда один элемент больше другого, это, скорее, показатель его важности. Хороший пример этого — aside и main. Размер заголовка в разделе <aside> должен быть меньше, чем размер заголовка в разделе <main>.
Обратите внимание на то, что заголовок в теге aside меньше, чем заголовок в main. Мы легко можем сделать это благодаря единицам запросов. Во-первых, нам нужно определить aside и main как внутренние контейнеры.
1 2 3 4 |
aside, main { container: inline-size; } |
Затем мы будем использовать единицы запроса для заголовка раздела. Мы также можем использовать еденицы запроса для нижнего поля.
1 2 3 4 |
.section-title { font-size: clamp(1.25rem, 3qw, 2rem); margin-bottom: clamp(0.5rem, 1.5qw, 1rem); } |
Компонент bio
Компонент bio может находиться в меньшем контейнере (например, на боковой панели), отображаться в мобильном окне просмотра или в большом контейнере, таком как заголовок страницы.
Мы можем создать компонент, который может адаптироваться к ширине своего контейнера. В этом примере размер аватара и шрифта пользователя изменяется в зависимости от ширины контейнера.
1 2 3 4 5 6 7 8 9 10 |
.bio { container: inline-size; } .c-avatar { --size: calc(60px + 10qw); width: var(--size, 100px); height: var(--size, 100px); margin-bottom: clamp(0.5rem, 3qmin, 2rem); } |
Заголовки cо cчетчиками
В некоторых случаях нам нужно показывать счетчик рядом с заголовком с телом статьи. Это идеальный вариант использования единиц запроса.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.article-body { counter-reset: heading; } h2 { container: inline-size; font-size: clamp(1.25rem, 3qw, 2rem); margin-bottom: clamp(0.5rem, 1.5qw, 1rem); } h2:before { --size: calc(1.25rem + 3qw); content: counter(heading); counter-increment: heading; width: var(--size); height: var(--size); font-size: calc(0.85rem + 1qw); margin-right: calc(var(--size) / 4); } |
Динамические зазоры
Мы можем использовать единицы просмотра для создания динамических зазоров с помощью сетки CSS. Что-то вроде:
1 2 3 |
.wrapper { gap: calc(1rem + 2vw); } |
Это круто, но как насчет компонентов в определенных оболочках? Использование единиц просмотра не сработает. Вот почему использование единиц запросов — хорошее решение в таком случае.
1 2 3 4 5 |
.card { display: flex; flex-direction: column; gap: calc(0.5rem + 1qmin); } |
Зазор будет немного больше, когда компонент переключится на горизонтальный стиль. Что произойдет, если мы будем использовать блоки запроса без определения контейнера?
Согласно спецификации: Если подходящий контейнер запроса недоступен, используйте небольшой размер области просмотра для этой оси.
Браузер будет обрабатывать единицы запроса, как если бы они были единицами просмотра. Рассмотрим следующий пример:
1 2 3 |
h2 { font-size: clamp(1.25rem, 3qw, 2rem); } |
Если для элемента не определен контейнер h2, браузер будет считать, что 3qw — это 3% ширины области просмотра. Это значит, что использование единиц запроса без определения контейнера может привести к неожиданным результатам. Надеюсь, вам понравилась статья. Спасибо за чтение!
Автор: Ahmad Shadeed
Источник: ishadeed.com
Редакция: Команда webformyself.
Читайте нас в Telegram, VK, Яндекс.Дзен