Grid: карточная сетка

Grid-карточная сетка — адаптивный ряд карточек с одинаковой или автоматической шириной, реализованный через repeat(auto-fill, minmax(..., 1fr)).

Зачем нужно

Grid превосходит Flexbox для карточных сеток: последняя строка не растягивается, элементы всегда выровнены по двум осям, нет необходимости в calc для отнимания gap. Паттерн auto-fill + minmax — золотой стандарт адаптивных сеток без медиазапросов.

Где используется

  • Каталог товаров
  • Список статей/карточек контента
  • Портфолио проектов
  • Список пользователей
  • Раздел с функциями продукта

Основной контент

Адаптивная сетка без медиазапросов

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
}

Это самый мощный паттерн: карточки автоматически перестраиваются от 1 до N колонок по ширине контейнера.

Фиксированное количество колонок

/* 3 колонки */
.cards-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

/* Адаптив */
@media (max-width: 900px) {
  .cards-3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 500px) {
  .cards-3 { grid-template-columns: 1fr; }
}

Карточка с равной высотой

.card {
  display: flex;
  flex-direction: column;  /* Внутренний Flexbox */
  background: white;
  border-radius: 8px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.1);
  overflow: hidden;
}

.card__image {
  aspect-ratio: 16/9;
  object-fit: cover;
  width: 100%;
}

.card__body {
  flex: 1;
  padding: 16px;
}

.card__footer {
  padding: 12px 16px;
  border-top: 1px solid #f0f0f0;
}

auto-fill vs auto-fit

/* auto-fill: создаёт колонки, даже если нет элементов */
.fill {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
/* При 3 карточках в широком контейнере: [card][card][card][empty][empty] */

/* auto-fit: расширяет существующие колонки, игнорирует пустые */
.fit {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* При 3 карточках в широком контейнере: [card][card][card] — равномерно */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.card--featured {
  grid-column: span 2;   /* Занимает 2 колонки */
}

Частые ошибки

  • auto-fill с minmax(0, 1fr) — без минимальной ширины колонки схлопываются до нуля; всегда указывайте разумный min
  • Конфликт auto-fill и max-width на карточке — если у карточки max-width, она не заполнит ячейку; убирайте ограничение или добавляйте justify-items: center
  • auto-fit vs auto-fill при одной карточкеauto-fit растянет её на всю ширину; если это нежелательно, используйте auto-fill

Связанные темы

Ресурсы