Привет, коллега! Если ты PHP-разработчик, то наверняка сталкивался с ситуацией, когда верстка ломается после добавления нового блока. Или когда нужно сделать сложную сетку, а flexbox плачет. Сегодня я расскажу, как использовать CSS Grid для макетов, которые кажутся невозможными. Без фреймворков, без магии — только CSS. Поехали!

Почему Grid, а не Flexbox?

Flexbox — это одномерная система. Она работает либо в строку, либо в столбец. Grid же двумерный. Представь шахматную доску: ты можешь двигать фигуры и по горизонтали, и по вертикали одновременно. Для сложных макетов это спасение.

Допустим, у тебя есть страница с хедером, сайдбаром, контентом и футером. Flexbox заставит тебя вкладывать контейнеры друг в друга. Grid же сделает это одной строкой кода.

Основы, которые нужно знать

Прежде чем лезть в дебри, давай освежим базовые свойства. Вот таблица, которая пригодится:

Свойство Описание Пример значения
grid-template-columns Определяет количество и ширину колонок 1fr 2fr 1fr
grid-template-rows Определяет количество и высоту строк auto 100px 1fr
grid-gap Отступы между ячейками 10px 20px
grid-area Задает имя области для элемента header

Но это база. Теперь перейдем к продвинутым штукам.

Именованные области и вложенные сетки

Представь, что ты верстаешь личный кабинет. Есть шапка, меню слева, основной контент и блок с чатом. Вместо того чтобы мучиться с классами, используй grid-template-areas.

.dashboard {
  display: grid;
  grid-template-columns: 200px 1fr 300px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "sidebar main chat"
    "footer footer footer";
  gap: 10px;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.chat { grid-area: chat; }
.footer { grid-area: footer; }

Но что, если внутри main нужно сделать еще одну сетку? Легко! Просто сделай main тоже гридом:

.main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 15px;
}

Это называется вложенные сетки. Они работают как матрешки. Главное — не переусердствуй, иначе код превратится в лапшу.

Правило: Если видишь, что в одном блоке нужно разместить больше 3-4 элементов в строку — используй вложенный грид. Но не делай глубину больше 2 уровней, иначе сложно дебажить.

Адаптивность без медиа-запросов

Звучит как фантастика, но это реально. Используй auto-fill и minmax. Например, сетка для карточек товаров:

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

Что здесь происходит? Браузер сам решает, сколько колонок поместится, чтобы ширина каждой была не меньше 250px. Если экран узкий — будет одна колонка, если широкий — три или четыре. Без единого медиа-запроса.

Но есть нюанс: если карточек мало, они растянутся на всю ширину. Чтобы этого избежать, добавь max-width контейнеру.

Анимация грид-элементов

Да, Grid поддерживает анимацию. Например, ты хочешь, чтобы при наведении на карточку она увеличивалась. Просто добавь transition:

.card {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
  transform: scale(1.05);
  box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}

Но если ты хочешь анимировать сами колонки (например, менять ширину), то это сложнее. Grid не анимирует grid-template-columns напрямую. Выход — использовать CSS-переменные:

.grid {
  --col-width: 1fr;
  grid-template-columns: var(--col-width) 2fr;
  transition: --col-width 0.5s;
}
.grid:hover {
  --col-width: 2fr;
}

Этот трюк работает в современных браузерах. Если нужно поддерживать старые, используй JavaScript.

Практический пример: дашборд с данными из PHP

Представь, что ты выводишь список заказов из БД. Каждый заказ — это карточка с id, статусом, суммой и действиями. Сделаем сетку, которая адаптируется под количество заказов.

$orders = [
  ['id' => 1, 'status' => 'Новый', 'amount' => 1500],
  ['id' => 2, 'status' => 'В обработке', 'amount' => 2300],
  // ...
];
?>
<div class="orders-grid">
  <?php foreach ($orders as $order): ?>
    <div class="order-card">
      <h3>Заказ #<?= $order['id'] ?></h3>
      <p>Статус: <?= $order['status'] ?></p>
      <p>Сумма: <?= $order['amount'] ?> руб.</p>
      <button>Подробнее</button>
    </div>
  <?php endforeach; ?>
</div>
.orders-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 15px;
  padding: 20px;
}
.order-card {
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 15px;
  transition: transform 0.2s;
}
.order-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

Теперь, даже если заказов 100, сетка подстроится. А если 1 — карточка не растянется на всю ширину, потому что minmax задает минимум.

Частые ошибки и как их избежать

  • Переполнение контейнера. Если не задать overflow: hidden, элементы могут вылезти за границы. Всегда проверяй.
  • Слишком много фракций. 1fr — это не пиксели. Если смешиваешь fr с фиксированными значениями, считай внимательно.
  • Забываешь про gap. Без отступов сетка слипается. Добавляй gap всегда, даже если 0.

Лайфхак: Используй инструменты разработчика в браузере. Во вкладке Layout можно увидеть сетку, линии и области. Это спасет часы дебага.

Что в итоге

CSS Grid — это мощный инструмент, который делает верстку предсказуемой. Ты можешь создавать сложные макеты без костылей, адаптировать под любые экраны и даже анимировать. Главное — не бойся экспериментировать. Начни с малого: замени flexbox на grid в одном проекте. Уверен, ты почувствуешь разницу.

Помни: код должен быть читаемым. Именованные области, вложенные сетки и auto-fill — твои друзья. А если что-то пошло не так — всегда можно вернуться к flexbox. Но теперь ты знаешь, что есть путь лучше.

Студия WNDER