Адаптивная сетка на CSS Grid: auto-fit, auto-fill и minmax — простое руководство

CSS Grid — самый простой способ собрать адаптивную сетку карточек, галерей и списков товаров без десятка @media. Ключ к магии — связка repeat(auto-fit, minmax()). Разберём её шаг за шагом, покажем практичные паттерны и частые ошибки, чтобы вы сразу применили это в продакшене.
Задача, которую решаем
- Карточки автоматически переносятся на новую строку без медиазапросов.
- Минимальная ширина карточки соблюдается, контент не ломается.
- Отступы стабильны, верстка «дышит».
Быстрый старт: базовая сетка (не адаптивная)
Начнём с простого примера, который фиксирует три колонки и не подстраивается под экран.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
Такой код создаёт 3 равные колонки, но на узких экранах карточки начнут ужиматься слишком сильно.
Делаем адаптивно: minmax + auto-fit
Сделаем так, чтобы каждая карточка имела разумный минимум, а дальше растягивалась равномерно.
.grid {
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
Как это работает:
- minmax(220px, 1fr) — колонка не станет уже 220px, но может расти до 1fr (равная доля свободного места).
- auto-fit — автоматически «подгоняет» количество колонок под доступную ширину, «схлопывая» пустые дорожки.
auto-fit vs auto-fill: в чём разница?
Оба пытаются разместить максимум колонок, но пустые дорожки ведут себя по-разному:
- auto-fit — схлопывает пустые дорожки, элементы растягиваются и равномерно занимают строку.
- auto-fill — сохраняет «призрачные» колонки, из-за чего видимые элементы не растягиваются до края.
/* Растягивать карточки на всю ширину строки */
.grid-fit { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
/* Оставлять фиксированную сетку с пустыми местами */
.grid-fill { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
В большинстве случаев для карточек удобнее auto-fit — визуально сетка выглядит «плотнее».
Отступы и выравнивание
.grid {
display: grid;
gap: clamp(12px, 2vw, 24px); /* адаптивные отступы */
align-items: stretch; /* элементы равной высоты в строке */
}
.card {
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 16px;
box-sizing: border-box;
}
Карточка с кнопкой, прижатой к низу
Частая задача: заголовок, текст любой длины и кнопка снизу. Удобно решить внутренней сеткой карточки.
.card {
display: grid;
grid-template-rows: auto 1fr auto; /* контент растягивается, кнопка внизу */
gap: 12px;
}
.card__title { font-weight: 600; }
.card__text { color: #4b5563; }
.card__btn { align-self: end; }
Полный рабочий пример: сетка карточек
<section class="catalog">
<div class="grid">
<article class="card">
<h3 class="card__title">Карточка №1</h3>
<p class="card__text">Короткое описание товара или статьи.</p>
<button class="card__btn">Подробнее</button>
</article>
<article class="card">
<h3 class="card__title">Карточка №2</h3>
<p class="card__text">Здесь текста побольше, чтобы показать, что высота карточек в строке выравнивается автоматически по самой высокой.</p>
<button class="card__btn">Подробнее</button>
</article>
<!-- ... ещё карточки ... -->
</div>
</section>
/* CSS */
.catalog {
padding: 24px;
background: #f8fafc;
}
.grid {
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.card {
display: grid;
grid-template-rows: auto 1fr auto;
gap: 12px;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 16px;
box-sizing: border-box;
}
.card__title { margin: 0; font-size: 18px; }
.card__text { margin: 0; line-height: 1.5; color: #4b5563; }
.card__btn { justify-self: start; }
Когда пригодится auto-fill
Используйте auto-fill, если хотите сохранить «ритм» сетки и равные ширины даже при нехватке элементов (например, в админке, где ожидается фиксированная сетка).
.admin-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
Частые ошибки и как их избежать
- Слишком маленький min: minmax(120px, 1fr) приводит к узким «палкам». Подбирайте реальный минимум (обычно 200–280px).
- Перепутанные аргументы minmax: min должен быть меньше max. Пишите minmax(240px, 1fr), а не наоборот.
- Жёсткие фиксированные ширины внутри карточки: большие изображения без ограничений ломают сетку. Используйте max-width: 100% и aspect-ratio.
- Забытый box-sizing: добавляйте box-sizing: border-box, чтобы паддинги не «распирали» колонки за пределы min.
- Непредсказуемые отступы: ставьте gap вместо margin между карточками — проще и надёжнее.
Ещё пара приёмов для устойчивой сетки
/* Предотвращаем скачки при загрузке изображений */
.card img {
width: 100%;
height: auto;
display: block;
aspect-ratio: 4 / 3; /* резервируем место под фото */
object-fit: cover;
}
/* Управление максимальной шириной контейнера */
.container {
width: min(100% - 32px, 1200px);
margin-inline: auto;
}
/* Адаптивные размеры без @media */
:root {
--space: clamp(12px, 2vw, 24px);
}
.grid { gap: var(--space); }
Итог
Связка repeat(auto-fit, minmax()) — базовый и крайне мощный приём для адаптивных сеток на CSS Grid. Он решает 80% кейсов карточек и галерей без медиазапросов. Освойте его, и ваши интерфейсы будут автоматически подстраиваться под ширину экрана, сохраняя аккуратный вид.
Хотите быстро перейти от теории к практике, собрать реальные макеты и закрепить знания по Grid, Flex и типографике? Попробуйте курс: Прокачать вёрстку на практике в курсе «Вёрстка сайта с нуля 2.0».
-
-
Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.