Готовые макеты: holy grail, sticky footer, карточки
Собираем из Grid и Flexbox проверенные временем макеты: holy grail, прилипающий футер, центрирование и резиновую сетку карточек.
Макетный паттерн — это готовый, многократно проверенный рецепт раскладки страницы (шапка-сайдбар-контент-футер, карточки, центрирование), который решает типовую задачу минимумом CSS.
Зачем это знать на практике
Девяносто процентов интерфейсов — это пять-шесть повторяющихся макетов. Зная их наизусть, вы не изобретаете велосипед на каждом проекте и не тащите тяжёлый фреймворк ради «шапки и сайдбара». Современные Grid и Flexbox решают классические задачи, на которые раньше уходили float-хаки и таблицы, буквально в несколько строк. Этот набор рецептов — ваш быстрый старт для любой страницы.
Holy Grail на Grid
«Святой Грааль» вёрстки — шапка, подвал во всю ширину и три колонки между ними (навигация, контент, сайдбар), где центральная тянется. Двадцать лет это была боль на float; на Grid — несколько строк с именованными областями:
.holy-grail {
display: grid;
grid-template:
"header header header" auto
"nav main aside " 1fr
"footer footer footer" auto
/ 200px 1fr 240px; /* ширины колонок после слэша */
min-height: 100vh;
gap: 16px;
}
.holy-grail > header { grid-area: header; }
.holy-grail > nav { grid-area: nav; }
.holy-grail > main { grid-area: main; }
.holy-grail > aside { grid-area: aside; }
.holy-grail > footer { grid-area: footer; }
Шорткат grid-template объединяет области, высоты строк и (после /) ширины колонок. Строка контента получает 1fr — она съедает всю свободную высоту, прижимая футер вниз. Боковые колонки фиксированы, main тянется. Под мобильный достаточно переписать одну карту областей в медиазапросе, сложив всё в столбик.
А вот разметка, к которой подключается этот CSS:
<div class="holy-grail">
<header>Шапка</header>
<nav>Навигация</nav>
<main>Основной контент</main>
<aside>Сайдбар</aside>
<footer>Подвал</footer>
</div>
Sticky footer: подвал у нижнего края
Прилипающий футер — когда контента мало, подвал всё равно прижат к низу окна, а не висит посреди экрана; когда контента много — футер уезжает вниз естественно. Самый чистый способ — flex-колонка с растущим контентом:
body {
min-height: 100vh; /* тело минимум на весь экран */
margin: 0;
display: flex;
flex-direction: column; /* шапка-контент-футер в столбик */
}
main { flex: 1; } /* контент забирает всё свободное место */
Здесь flex: 1 на main заставляет контент растянуться и вытолкнуть футер к низу. Альтернатива на Grid: body { min-height: 100vh; display: grid; grid-template-rows: auto 1fr auto; } — средняя строка 1fr делает то же самое. Не путайте этот приём с position: sticky — у них разные задачи: sticky приклеивает элемент при прокрутке, а sticky footer держит подвал внизу короткой страницы.
Резиновая сетка карточек одной строкой
Адаптивную галерею карточек, которая сама меняет число колонок, мы уже видели в уроке про Grid. Это настолько частый паттерн, что заслуживает повтора как самостоятельный рецепт:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
gap: 24px;
}
Обратите внимание на min(100%, 260px) внутри minmax: на очень узких экранах (уже 260px) это не даст карточке прорвать контейнер — её минимум станет равен 100% ширины, и она аккуратно займёт всю строку. Без этой обёртки на телефоне-«малыше» появилась бы горизонтальная прокрутка. Один auto-fill заменяет три-четыре медиазапроса «на 2 / 3 / 4 колонки».
Центрирование: раз и навсегда
«Как отцентрировать div» перестало быть мемом. И Flexbox, и Grid центрируют по обеим осям двумя-тремя свойствами:
/* Flexbox */
.center-flex {
display: flex;
justify-content: center; /* по горизонтали */
align-items: center; /* по вертикали */
min-height: 100vh;
}
/* Grid — ещё короче */
.center-grid {
display: grid;
place-items: center; /* сразу обе оси */
min-height: 100vh;
}
Шорткат place-items: center — это align-items: center плюс justify-items: center одной строкой. Для центрирования одного блока в Grid это самый лаконичный способ из существующих.
Панель «контент + действие по краям»
Ещё один вездесущий рецепт — шапка-тулбар, где заголовок слева, кнопки справа, всё по центру вертикали:
.toolbar {
display: flex;
align-items: center;
justify-content: space-between; /* раскидать по краям */
gap: 16px;
}
/* прижать конкретную группу вправо, не трогая остальных: */
.toolbar .actions { margin-left: auto; }
Трюк margin-left: auto на элементе flex-строки съедает всё свободное место слева от него и толкает его (и всё, что правее) к правому краю — удобно, когда space-between не подходит из-за числа элементов.
Как это работает под капотом
Все эти паттерны опираются на два механизма. Первый — 1fr и flex: 1, которые поглощают свободное пространство по своей оси; именно они «выталкивают» футер вниз и растягивают центральную колонку. Второй — связка min-height: 100vh + растущий трек: высота вьюпорта задаёт минимум, а 1fr/flex: 1 распределяет остаток, поэтому на короткой странице футер всё равно у нижнего края, а на длинной — уезжает за экран. Центрирование же работает потому, что и Grid, и Flexbox умеют выравнивать по двум осям сразу, чего не давала старая поточная модель: place-items/(justify-content + align-items) ставят единственный элемент ровно в середину контейнера независимо от его размеров. Понимание этой пары — «кто ест свободное место» и «кто выравнивает по двум осям» — позволяет собрать почти любой макет без подбора магических чисел.
Частые ошибки
Sticky footer без min-height на контейнере. Если у body нет min-height: 100vh, растущему main нечего растягивать на короткой странице, и футер всплывает к середине. Минимум по высоте обязателен.
Карточки без min() переполняют узкий экран. minmax(260px, 1fr) на телефоне уже 260px даёт горизонтальную прокрутку; обёртка min(100%, 260px) это снимает.
Путают sticky footer и position: sticky. Это разные вещи: первый держит подвал внизу короткой страницы (Flexbox/Grid), второй приклеивает элемент при прокрутке (position: sticky; top: 0).
Лишний margin: 0 auto при flex-центрировании. Привычка центрировать блок через margin: 0 auto внутри уже flex-контейнера сбивает выравнивание — здесь достаточно justify-content/align-items на родителе.
Итоги
- Holy Grail собирается на Grid через
grid-templateс именованными областями; строка контента1frприжимает футер. - Sticky footer — это flex-колонка (
flex-direction: column) или Grid (grid-template-rows: auto 1fr auto) приmin-height: 100vhиflex: 1/1frна контенте. - Резиновая галерея:
repeat(auto-fill, minmax(min(100%, 260px), 1fr))— обёрткаmin()спасает от прокрутки на узких экранах. - Центрирование:
place-items: center(Grid) илиjustify-content+align-items(Flexbox). - Под капотом всё держится на «кто ест свободное место» (
1fr/flex: 1) и «кто выравнивает по двум осям».