Grid areas

grid-template-areas позволяет визуально описать макет сетки через именованные области, а grid-area привязывает элементы к этим областям.

Зачем нужно

Именованные области делают макет читаемым как ASCII-рисунок. Код становится самодокументирующимся: глядя на grid-template-areas, сразу видно структуру страницы. Это также упрощает адаптивность — достаточно переписать «карту» областей в медиа-запросе.

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

  • Макеты страниц (header, sidebar, content, footer)
  • Адаптивные макеты — разная «карта» для разных экранов
  • Сложные дашборды с виджетами
  • Любые макеты, где важна визуальная читаемость кода

Предпосылки

Синтаксис grid-template-areas

.layout {
  display: grid;
  grid-template-columns: 250px 1fr 300px;
  grid-template-rows: 80px 1fr 60px;
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";
  gap: 0;
  min-height: 100dvh;
}

Привязка элементов к областям

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }
<div class="layout">
  <header class="header">Header</header>
  <nav class="sidebar">Sidebar</nav>
  <main class="content">Content</main>
  <aside class="aside">Aside</aside>
  <footer class="footer">Footer</footer>
</div>

Правила именования

Пустые ячейки — точка (.)

.grid {
  grid-template-areas:
    "header header header"
    "sidebar content ."
    "footer  footer  footer";
  /* Правая верхняя ячейка пуста */
}

/* Несколько точек подряд = одна пустая ячейка */
.grid {
  grid-template-areas:
    "header header header"
    "sidebar content ......"
    "footer  footer  footer";
}

Области должны быть прямоугольными

/* ПРАВИЛЬНО — прямоугольная область */
.grid {
  grid-template-areas:
    "a a b"
    "a a c";
  /* "a" занимает 2x2 — прямоугольник */
}

/* ОШИБКА — L-образная область невалидна */
.grid {
  grid-template-areas:
    "a a b"
    "a c c"; /* "a" не прямоугольник! */
}

Каждая строка — одна строка сетки

.grid {
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto auto auto;
  grid-template-areas:
    "one   two   three"  /* строка 1 */
    "four  five  six"    /* строка 2 */
    "seven eight nine";  /* строка 3 */
}

Адаптивный макет через areas

/* Desktop */
.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar content"
    "footer  footer";
  min-height: 100dvh;
}

/* Tablet */
@media (max-width: 1024px) {
  .layout {
    grid-template-columns: 200px 1fr;
  }
}

/* Mobile — одна колонка */
@media (max-width: 768px) {
  .layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
    /* Sidebar ушёл под контент */
  }
}

.header  { grid-area: header;  }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer  { grid-area: footer;  }

Сокращённое свойство grid-template

.layout {
  display: grid;
  grid-template:
    "header  header"  80px
    "sidebar content" 1fr
    "footer  footer"  60px
    / 250px 1fr;
  /* Формат: "areas" row-size / column-sizes */
}

grid-area как сокращение для линий

grid-area можно использовать и без именованных областей:

.item {
  /* grid-area: row-start / col-start / row-end / col-end */
  grid-area: 1 / 1 / 3 / 3;

  /* Эквивалент: */
  grid-row: 1 / 3;
  grid-column: 1 / 3;
}

Именованные линии из areas

Когда вы создаёте именованную область, Grid автоматически создаёт именованные линии:

.grid {
  grid-template-areas:
    "header header"
    "sidebar content";
}

/* Автоматически создаются линии: */
/* header-start, header-end */
/* sidebar-start, sidebar-end */
/* content-start, content-end */

.element {
  /* Можно ссылаться на автоматические линии */
  grid-column: sidebar-start / content-end;
}

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

.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto auto 1fr;
  grid-template-areas:
    "stats1 stats2 stats3 stats4"
    "chart  chart  chart  table"
    "chart  chart  chart  table";
  gap: 16px;
  padding: 16px;
}

.stats1 { grid-area: stats1; }
.stats2 { grid-area: stats2; }
.stats3 { grid-area: stats3; }
.stats4 { grid-area: stats4; }
.chart  { grid-area: chart; }
.table  { grid-area: table; }

/* Мобильная версия */
@media (max-width: 768px) {
  .dashboard {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "stats1 stats2"
      "stats3 stats4"
      "chart  chart"
      "table  table";
  }
}

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

  1. Не прямоугольная область — Grid отклонит всё правило:
    /* ОШИБКА */
    grid-template-areas:
      "a b b"
      "a a b"; /* "a" и "b" — не прямоугольники */
    
  2. Разное количество ячеек в строках:
    /* ОШИБКА */
    grid-template-areas:
      "a b c"
      "d e";   /* 3 vs 2 — невалидно */
    
  3. Имя области = имя CSS-свойства — не используйте span, auto, inherit как имена
  4. Забыли grid-area на элементе — элемент размещается автоматически, игнорируя области

Практика

  • Создать макет с header + sidebar + content + footer через grid-template-areas
  • Сделать адаптивную версию с другой «картой» для мобильных
  • Реализовать дашборд с виджетами разного размера
  • Использовать точки (.) для пустых ячеек
  • Попробовать сокращённый синтаксис grid-template

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

Ресурсы