Что, если использовать контейнерные единицы измерения для... всего

Источник: «What if you used Container Units for… everything?»
Однажды я спросил себя: а что, если использовать контейнерные единицы измерения для каждого элемента дизайна? Я задался этим вопросом, отчасти потому, что мне показалось, что ответ может быть таким: ну, тогда всё будет очень хорошо масштабироваться!

Контейнерные единицы измерения, если вы ещё не слышали о них, — это единицы измерения (такие, как px или rem, но более близкие к единицам измерения области просмотра, таким как vw или vi), имеющие размер в соответствии с контейнером, в котором они находятся.

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

Я поиграл с довольно простой сеткой из карт разного размера. Не считайте, что это демонстрация в хорошей форме, это просто то, что было использовано для составления плана.

See the Pen

Потенциальная проблема: Невозможно стилизовать запрашиваемый элемент

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

.card-wrap {
container: cardWrap / inline-size;

padding: 2cqi;
border-radius: 4cqi;

.card {
border-radius: 4cqi;
}
}

Выше, border-radius будет отличаться, несмотря на то, что выглядит одинаково, потому что контейнер, на который ссылаются единицы измерения, разный.

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

Потенциальное решение: Ничего не стилизуйте на контейнере

Будьте бдительны! Это избавит от головной боли, если во время определения container будете уверены, что не используете других стилей, основанных на размере. Если это означает добавление дополнительной бессмысленной обёртки <div>, что ж, это не идеально, поскольку вес DOM имеет значение, но, вероятно, это приемлемо.

Потенциальная проблема: Слишком маленький и слишком большой

Если для чего-то вроде font-size использовать только контейнерные единицы, можно легко попасть в ситуацию, когда текст и элементы, основанные на тексте, окажутся либо слишком большими, либо слишком маленькими.

Здесь текст на большей карточке кажется слишком большим, но теги в порядке. Текст на меньшей открытке кажется нормальным, но теги слишком маленькие.
Здесь текст на большей карточке кажется слишком большим, но теги в порядке. Текст на меньшей открытке кажется нормальным, но теги слишком маленькие.

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

Использование только единиц контейнера (или единиц области просмотра) — плохая практика для определения размера текста. Однако это можно исправить.

Потенциальное решение: clamp

Убедиться в том, что текст не становится слишком маленьким или слишком большим, можно с помощью CSS функции clamp(). А чтобы убедиться, что предпочтения пользователей по размеру шрифта соблюдены, можно добавить относительную единицу измерения.

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

.tag {
/* Не делайте так */
font-size: 4cqi;

/* Делайте так */
font-size: clamp(16px, 4cqi + 0.5rem, 24px);
}

Потенциальная проблема: Строки vs столбцы

Один из важных вариантов использования контейнерного запроса — это изменение макета в контейнере на основе точек прерывания. Если контейнер меняется из широкого и короткого в узкий и длинный, то основанные на ширине (вероятно, наиболее распространённые) единицы измерения контейнера будут сильно отличаться.

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

Бонусная проблема: нельзя использовать единицы измерения контейнера для установки grid-template-columns, поскольку они не могут быть основаны на элементе, ширина которого точно такая же, как у грида.

Бонусная проблема: нельзя использовать единицы измерения контейнера для установки grid-template-columns, поскольку они не могут быть основаны на элементе, ширина которого точно такая же, как у грида.

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

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

Потенциальное решение: Используйте другие единицы измерения

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

В этом случае возможно подойдёт что-то вроде единицы cqmax, так что единица будет основана на самом длинном ребре контейнера.

.actions {
container: actions / inline-size;

svg {
display: block;
width: 4cqmax;
min-width: 24px;
max-width: 100%;
aspect-ratio: 1;
}
}

Но… нет. Это слишком необычно. Я бы посоветовал просто использовать относительные единицы или пиксели или что-то в этом роде.

В конце концов, если контейнерные единицы помогают добиться эффекта масштабирования в зависимости от размера элемента, которого вы хотите добиться, — дерзайте! Контейнерные запросы хорошо поддерживаются. Но не стоит перегибать.

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

Дополнительные материалы

Предыдущая Статья

Примеры использования cURL

Следующая Статья

Зачем нужна типизация массивов в PHP