$ sudo teach IT

Добро пожаловать на третий курс! На первых двух курсах вы научились размечать страницы, оформлять их и строить гибкие макеты на Flexbox. Теперь мы освоим CSS Grid — инструмент для двумерных сеток, где элементы раскладываются сразу по строкам и столбцам. Вместе с Grid вы научитесь позиционировать элементы поверх других и делать вёрстку адаптивной — чтобы сайт одинаково хорошо выглядел на телефоне, планшете и большом экране.

Курс, как и прежде, строится вокруг сквозного проекта: мы возьмём наш сайт компании и превратим его макет в аккуратную двумерную сетку, а затем сделаем адаптивным. Каждый урок добавляет к проекту новую возможность, и к концу у вас будет современная страница, которая безупречно подстраивается под любой экран. Начнём с фундамента сеток — grid-контейнера.

Зачем это нужно

Flexbox отлично выстраивает элементы вдоль одной линии — в ряд или в колонку. Но многие макеты двумерны: галерея карточек, где нужно задать и число столбцов, и высоту строк; макет страницы с шапкой, боковой панелью и подвалом. Расставлять такое одним Flexbox неудобно — приходится вкладывать контейнеры друг в друга. CSS Grid создан именно для двумерных раскладок: вы описываете сетку из строк и столбцов, а браузер сам расставляет элементы по ячейкам.

После этого урока вы сможете превращать любой контейнер в grid, задавать в нём столбцы и строки нужного размера и управлять расстоянием между ячейками — а это основа всех сеточных макетов.

Что уже умеем / что добавим

Вы умеете строить одномерные раскладки на Flexbox и наводить порядок в CSS. Теперь добавим второе измерение — сетку из строк и столбцов. В сквозном проекте мы возьмём блок с карточками услуг и разложим его в аккуратную grid-сетку вместо простого ряда.

Что вы узнаете в рамках статьи

  • Чем Grid отличается от Flexbox и когда он удобнее.
  • Как включить сетку свойством display: grid.
  • Как задавать столбцы и строки через grid-template-columns и grid-template-rows.
  • Что такое единица fr и как ей делить пространство.
  • Как задавать расстояние между ячейками свойством gap.

Ключевые термины

  • CSS Grid — модуль CSS для двумерных раскладок по строкам и столбцам.
  • Grid-контейнер — элемент, которому задано display: grid.
  • Grid-элементы — прямые дочерние элементы контейнера, попадающие в ячейки.
  • Ячейка (cell) — пересечение строки и столбца сетки.
  • fr — доля свободного пространства контейнера (fraction).
  • gap — расстояние между строками и столбцами сетки.

Что такое Grid и чем он отличается от Flexbox

CSS Grid (сеточная раскладка) позволяет разложить элементы сразу по двум измерениям — строкам и столбцам одновременно. Если Flexbox думает линиями («выстрой детей вдоль одной оси»), то Grid думает таблицей: вы заранее задаёте разметку сетки, а элементы занимают её ячейки.

Отсюда простое правило выбора: одномерная раскладка вдоль одной линии — берём Flexbox; двумерная сетка, где важны и столбцы, и строки, — берём Grid. Они не конкурируют, а дополняют друг друга, и в реальных проектах часто работают вместе. Как и во Flexbox, раскладкой управляет контейнер, а подчиняются ей его прямые дети.

Включаем сетку: display: grid

Чтобы контейнер стал сеткой, ему задают display: grid. Сам по себе этот код ещё не создаёт столбцов — он лишь включает grid-режим. Возьмём блок с шестью карточками:

<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell">5</div>
  <div class="cell">6</div>
</div>
.grid {
  display: grid;
}

После этого правила .grid становится grid-контейнером, а шесть .cell — его grid-элементами. Пока столбцы не заданы, сетка состоит из одного столбца, и карточки идут друг под другом. Чтобы получить настоящую сетку, нужно описать её столбцы — этим займёмся дальше.

Задаём столбцы: grid-template-columns

Число и ширину столбцов задаёт свойство grid-template-columns. Вы перечисляете размеры столбцов через пробел, и сколько значений напишете — столько столбцов и получите:

.grid {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}

Здесь мы описали три столбца по 200 пикселей. Наши шесть карточек заполнят сетку по порядку: первые три встанут в первую строку, следующие три — во вторую. Строки при этом создаются автоматически по мере необходимости — их число подстраивается под количество элементов.

Фиксированные пиксели удобны не всегда: хочется, чтобы столбцы делили доступную ширину поровну. Для этого есть единица fr — доля свободного пространства:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

Запись 1fr 1fr 1fr означает «три равных столбца», которые вместе занимают всю ширину контейнера и делят её поровну. Если задать 2fr 1fr 1fr, первый столбец станет вдвое шире каждого из остальных. В отличие от процентов, fr учитывает gap и не приводит к переполнению — поэтому для сеток это самая удобная единица.

Строки и расстояние: grid-template-rows и gap

По аналогии со столбцами высоту строк задаёт grid-template-rows. Часто высоту строк оставляют на усмотрение содержимого, но при необходимости её можно задать явно:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 150px 150px;
}

Эта сетка имеет три столбца и две строки по 150 пикселей. Осталось развести ячейки, чтобы они не липли друг к другу. Раньше для этого использовали внешние отступы, но в Grid есть специальное свойство gap — расстояние между строками и столбцами:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 20px;
}

Свойство gap: 20px добавит по 20 пикселей между всеми соседними ячейками — и по горизонтали, и по вертикали, но без лишних отступов по краям контейнера. Можно задать разные значения: gap: 20px 40px — это 20 пикселей между строками и 40 между столбцами. Именно gap — правильный способ разредить сетку, куда удобнее ручных margin у каждой карточки.

Применяем в проекте

Вернёмся к сайту компании. Раньше карточки услуг стояли простым рядом на Flexbox. Разложим их в аккуратную сетку из трёх столбцов с одинаковыми промежутками.

<section class="services">
  <div class="card">Дизайн</div>
  <div class="card">Разработка</div>
  <div class="card">Поддержка</div>
  <div class="card">Аналитика</div>
  <div class="card">Реклама</div>
  <div class="card">Консультации</div>
</section>
.services {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 24px;
}

Обновите страницу: шесть карточек выстроились в ровную сетку — три в ряд, с одинаковыми отступами между ними, а вторая тройка аккуратно перешла на следующую строку. Столбцы поделили ширину поровну благодаря fr, а gap развёл карточки на равное расстояние. Мы задали всё это тремя строчками — и получили настоящий двумерный макет.

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

  • Забыть display: grid.
    Свойства grid-template-* и gap работают только внутри grid-контейнера; без display: grid они не действуют.
  • Свойства сетки не на том элементе.
    grid-template-columns задают контейнеру, а не самим карточкам.
  • Проценты вместо fr.
    Три столбца по 33% вместе с gap дадут переполнение; fr учитывает промежутки и делит место корректно.
  • Ручные margin вместо gap.
    Отступы у каждой ячейки ломают ровные края сетки; используйте gap.

Итоги

Поздравляем с началом третьего курса и первым шагом в мир двумерных макетов! Вы узнали, чем Grid отличается от Flexbox, научились включать сетку свойством display: grid, задавать столбцы и строки через grid-template-columns и grid-template-rows, делить пространство удобной единицей fr и разводить ячейки с помощью gap. Вы даже разложили карточки услуг в настоящую сетку — макет вашего сайта стал заметно профессиональнее.

Отличный старт — так держать! В следующем уроке мы разберёмся с единицами и функциями fr, repeat() и minmax(), которые позволят описывать сетки короче и гибче.

На следующий урок