Элемент с классом
container или wrapper часто используется в вёрстке, чтобы ограничить ширину контента на десктопных экранах. Стили классического резинового контейнера выглядят примерно так:.container {
width: 100%;
max-width: 1400px;
padding-right: 16px;
padding-left: 16px;
margin-right: auto;
margin-left: auto;
}width: 100% не обязательно указывать, но это нужно для случаев, когда контейнер находится внутри flex-контекста. max-width ограничивает ширину контейнера. padding задаёт отступы, чтобы контент не прилипал к краям на узких экранах, а margin со значением auto используется для горизонтального центрирования. Обычно контейнер применяется так:<section class="section">
<div class="container">
<!-- Контент первой секции -->
</div>
</section>
<section class="section">
<div class="container">
<!-- Контент второй секции -->
</div>
</section>
У секции может быть фон на всю ширину страницы. А контент внутри должен быть ограничен по ширине и центрирован. Получается вложенность контейнера в секцию.
На одном проекте я решил переосмыслить подход к контейнеру, основываясь на двух идеях:
1. попробовать более новые возможности CSS.
2. избежать лишнего DOM-элемента и вложенности.
И вот что у меня получилось:
:root {
--container-max-width: 1400px;
--container-min-field: 16px;
--container-field: calc(
(var(--vw) - var(--container-max-width)) / 2
);
}
.container {
width: 100%;
padding-inline: max(
var(--container-field),
var(--container-min-field)
);
}В
:root объявлены пользовательские свойства:-
--container-max-width — максимальная ширина контейнера.-
--container-min-field — минимальный размер одного поля, чтобы контент не прилипал к краям экрана.-
--container-field — динамический размер одного поля, который вычисляется так: от ширины вьюпорта отнимается максимальная ширина контейнера и делится на 2. В итоге получается тот размер, который обычно достигается через margin со значением auto.Ширина области просмотра в формуле представлена пользовательским свойством
--vw, чтобы учесть ширину прокрутки. Про это есть отдельный пост.Далее используется функция
max(), чтобы выбрать максимальное значение из динамического и минимального поля. На десктопе поле будет занимать всё свободное пространство от края экрана до контентной области контейнера, а на узких экранах поле будет минимальной ширины.Работает это аналогично классическому контейнеру. Благодаря полям вместо отступов на одном узле можно и фон использовать, и ширину контента ограничить. То есть смиксовать секцию и контейнер, говоря терминами БЭМ.
<section class="container section">
<!-- Контент -->
</section>
#css