Слишком долго веб-разработчики сталкивались со сложными и часто хрупкими методами создания двумерных макетов в интернете. Позиционирование с помощью флоатов, таблиц и даже ранние хаки с inline-block были распространены, но никогда не были по-настоящему удовлетворительными. Затем появился CSS Grid Layout, который стал настоящей революцией, предоставив нативный, мощный и интуитивно понятный способ проектирования интерфейсов на основе сетки.
Если вы готовы отказаться от разочарований в макетах и принять современный, эффективный подход, вы попали по адресу. Этот исчерпывающий гид проведет вас от полного новичка до уверенного создания сложных макетов на основе сетки.
Что такое CSS Grid Layout?
CSS Grid Layout, часто называемый просто «Grid», — это двумерная система макета для веба. Это означает, что она может одновременно обрабатывать как столбцы, так и строки, позволяя вам проектировать точные и гибкие макеты для ваших веб-страниц. Представьте это как электронную таблицу для ваших HTML-элементов, где вы определяете структуру, а затем размещаете свой контент в этой структуре.
Почему использовать CSS Grid?
- Двумерный контроль: В отличие от Flexbox (который в основном одномерный — либо строки, ЛИБО столбцы), Grid позволяет вам контролировать оба измерения одновременно, что делает его идеальным для общих макетов страниц.
- Семантический HTML: Grid отделяет макет от контента, что означает, что вы можете писать более чистый и семантический HTML без необходимости добавлять дополнительные обертки div только для целей макета.
- Упрощенная адаптивность: Создание адаптивных дизайнов становится значительно проще с Grid, так как вы можете переопределить структуру сетки с помощью медиазапросов или использовать встроенные функции, такие как
minmax()иauto-fit/auto-fill. - Явное размещение: Вы можете точно размещать элементы где угодно на вашей сетке, определяя их начальные и конечные точки как для строк, так и для столбцов.
- Неявное создание сетки: Grid может автоматически создавать строки и столбцы по мере необходимости, что делает его гибким для динамического контента.
Поддержка браузеров
CSS Grid широко поддерживается во всех современных браузерах. Вы можете уверенно использовать его в своих проектах, не беспокоясь о серьезных проблемах совместимости.
Начало работы: Основы CSS Grid
Чтобы использовать CSS Grid, вам нужны два основных компонента:
- Контейнер сетки: Родительский элемент, который будет содержать ваши элементы сетки.
- Элементы сетки: Непосредственные дочерние элементы контейнера сетки, которые будут располагаться в соответствии с сеткой.
1. Определение контейнера сетки: display: grid;
Первый шаг — объявить элемент контейнером сетки. Это делается с помощью свойства display: grid;.
Структура HTML:
<div class="container">
<div class="item">Элемент 1</div>
<div class="item">Элемент 2</div>
<div class="item">Элемент 3</div>
<div class="item">Элемент 4</div>
</div>
CSS:
.container {
display: grid;
/* Другие свойства сетки будут здесь */
}
.item {
background-color: lightblue;
border: 1px solid steelblue;
padding: 1rem;
text-align: center;
}
Просто установка display: grid; пока не изменит визуально много, так как сетка еще не была определена. Все непосредственные дочерние элементы станут элементами сетки, расположенными в одной колонне по умолчанию (или занимая столько места, сколько они естественно занимают).
2. Определение столбцов и строк: grid-template-columns и grid-template-rows
Эти свойства определяют структуру вашей сетки. Вы указываете размер каждого столбца и строки.
grid-template-columns
Определяет количество и ширину столбцов в вашей сетке.
.container {
display: grid;
grid-template-columns: 100px 200px 100px; /* Три столбца: 100px, 200px, 100px */
}
grid-template-rows
Определяет количество и высоту строк в вашей сетке.
.container {
display: grid;
grid-template-columns: 100px 200px 100px;
grid-template-rows: 50px 150px; /* Две строки: 50px, 150px */
}
Единицы в сеточном макете
Вы можете использовать различные единицы для определения размеров треков:
px: Фиксированные значения в пикселях.%: Процент от размера контейнера сетки.em,rem: Относительно размеров шрифта.auto: Занимает доступное пространство, распределяя его междуautoтреками.fr(доля): Это мощная новая единица, уникальная для Grid. Она представляет собой долю доступного пространства в контейнере сетки.
Пример с единицей fr:
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* Три столбца: 1 часть, 2 части, 1 часть доступного пространства */
grid-template-rows: auto 100px; /* Первая строка автоматической высоты, вторая строка 100px */
}
В приведенном выше примере, если контейнер имеет 400px доступного пространства, столбцы будут соответственно 100px, 200px и 100px.
Функция repeat()
Функция repeat() упрощает определение нескольких идентичных треков. Вместо 1fr 1fr 1fr 1fr вы можете написать repeat(4, 1fr).
.container {
display: grid;
grid-template-columns: repeat(4, 1fr); /* Четыре равных столбца */
grid-template-rows: repeat(2, 100px); /* Две строки, каждая 100px высотой */
}
Функция minmax()
minmax(min, max) определяет диапазон размеров для трека сетки. Трек не будет меньше min и не больше max.
.container {
display: grid;
grid-template-columns: repeat(3, minmax(100px, 1fr));
/* Три столбца, каждый шириной не менее 100px, но может увеличиваться до 1fr, если позволяет пространство */
}
Это невероятно полезно для адаптивных дизайнов, обеспечивая, чтобы элементы не становились слишком маленькими, при этом позволяя им расширяться.
3. Добавление пространства между треками: gap (ранее grid-gap)
Свойство gap (и его длинные формы row-gap и column-gap) определяет пространство между треками сетки.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 100px);
gap: 1rem; /* 1rem пространство между строками и столбцами */
/* Или:
row-gap: 1rem;
column-gap: 2rem;
*/
}
gap является сокращением для row-gap и column-gap. Если вы укажете одно значение, оно применяется ко всем. Если вы укажете два значения, первое будет для строк, а второе для столбцов (например, gap: 1rem 2rem;).
Размещение элементов на сетке
Как только вы определили свои треки сетки, вы можете указать элементам сетки, где начинать и заканчивать в этой структуре.
Явное размещение с номерами линий
Линии сетки автоматически нумеруются, начиная с 1. Вы можете использовать эти номера, чтобы точно размещать ваши элементы.
grid-column-start,grid-column-endgrid-row-start,grid-row-end
CSS:
.container {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 столбца */
grid-template-rows: repeat(3, 100px); /* 3 строки */
gap: 10px;
}
.item-1 {
grid-column-start: 1;
grid-column-end: 3; /* Элемент 1 охватывает от линии столбца 1 до линии столбца 3 (занимает 2 столбца) */
grid-row-start: 1;
grid-row-end: 2; /* Элемент 1 охватывает от линии строки 1 до линии строки 2 (занимает 1 строку) */
background-color: lightcoral;
}
.item-2 {
grid-column-start: 4;
grid-column-end: 5; /* Элемент 2 начинается на линии столбца 4, заканчивается на линии 5 (занимает 1 столбец) */
grid-row-start: 1;
grid-row-end: 3; /* Элемент 2 охватывает от линии строки 1 до линии строки 3 (занимает 2 строки) */
background-color: lightgreen;
}
Сокращения для размещения
Вы можете использовать сокращения для объединения свойств начала и конца:
grid-column: start / end;grid-row: start / end;
.item-1 {
grid-column: 1 / 3; /* То же самое, что grid-column-start: 1; grid-column-end: 3; */
grid-row: 1 / 2;
}
.item-2 {
grid-column: 4 / 5;
grid-row: 1 / 3;
}
Использование span для размещения
Вместо определения конечной линии вы можете указать, сколько треков должен охватывать элемент:
.item-1 {
grid-column: 1 / span 2; /* Начинается на линии 1, охватывает 2 столбца */
grid-row: 1 / span 1;
}
.item-2 {
grid-column: 4 / span 1;
grid-row: 1 / span 2;
}
Неявная сетка и автоматическое размещение
Если вы не размещаете все элементы явно, Grid автоматически разместит их в доступных ячейках. Вы можете контролировать это поведение:
grid-auto-flow: Контролирует, как автоматически размещенные элементы заполняют пространство.row(по умолчанию): Элементы заполняют строки, затем переходят к следующей строке.column: Элементы заполняют столбцы, затем переходят к следующему столбцу.dense: Пытается заполнить пустоты раньше в сетке, если более мелкие элементы появляются позже.
grid-auto-columns,grid-auto-rows: Определяют размер неявно созданных треков (когда элементы выходят за пределы явно определенной сетки).
Пример с grid-auto-flow:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px; /* Явно определенные строки 100px, любые автоматически сгенерированные строки также будут 100px */
gap: 10px;
grid-auto-flow: dense; /* Пытается заполнить пустые места */
}
Именование линий и областей сетки
Номера линий могут стать громоздкими для сложных макетов. Grid позволяет вам называть линии и определять «области».
Именование линий сетки
Вы можете добавлять имена к вашим линиям сетки в grid-template-columns и grid-template-rows. Это делает явное размещение более читаемым.
.container {
display: grid;
grid-template-columns: [col1-start] 1fr [col2-start] 1fr [col3-start] 1fr [col3-end];
grid-template-rows: [row1-start] auto [row2-start] 100px [row3-start] auto [row3-end];
}
.item-1 {
grid-column: col1-start / col2-start; /* Использует именованные линии */
grid-row: row1-start / row2-start;
}
Определение областей сетки: grid-template-areas и grid-area
Это очень интуитивный способ визуализировать и создать ваш макет. Вы «рисуете» свой макет, используя строки в grid-template-areas, а затем назначаете элементы этим областям, используя grid-area.
CSS:
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: auto 1fr auto;
gap: 1rem;
grid-template-areas:
"header header header"
"sidebar main content"
"footer footer footer";
}
.header {
grid-area: header;
background-color: #f8d7da;
}
.sidebar {
grid-area: sidebar;
background-color: #d1ecf1;
}
.main {
grid-area: main;
background-color: #d4edda;
}
.content {
grid-area: content;
background-color: #ffeeba;
}
.footer {
grid-area: footer;
background-color: #f8d7da;
}
HTML:
<div class="container">
<header class="header">Заголовок</header>
<aside class="sidebar">Боковая панель</aside>
<main class="main">Основной контент</main>
<div class="content">Дополнительный контент</div>
<footer class="footer">Нижний колонтитул</footer>
</div>
Каждая строка представляет собой строку, а слова в строке представляют области сетки в этой строке. Точка (.) обозначает пустую ячейку. Повторяющиеся имена означают, что элемент охватывает эти ячейки.
Выравнивание в CSS Grid
Grid предоставляет мощные свойства выравнивания, аналогичные Flexbox, как для элементов сетки, так и для треков сетки.
Выравнивание элементов сетки (внутри их ячейки/области)
justify-items: Выравнивает элементы вдоль оси строки (inline). Значения:start,end,center,stretch(по умолчанию).align-items: Выравнивает элементы вдоль оси столбца (block). Значения:start,end,center,stretch(по умолчанию).place-items: Сокращение дляalign-itemsиjustify-items. Например,place-items: center;
Эти свойства применяются к контейнеру сетки и влияют на все элементы сетки. Вы можете переопределить для отдельных элементов, используя justify-self, align-self и place-self.
CSS:
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(2, 100px);
gap: 10px;
justify-items: center; /* Все элементы выровнены по центру по горизонтали */
align-items: center; /* Все элементы выровнены по центру по вертикали */
}
.item-3 {
justify-self: start; /* Переопределение для элемента 3: выравнивание по началу по горизонтали */
align-self: end; /* Переопределение для элемента 3: выравнивание по концу по вертикали */
}
Выравнивание треков сетки (самой сетки внутри контейнера)
Эти свойства применяются, когда общий размер ваших треков сетки меньше, чем контейнер сетки, оставляя дополнительное пространство.
justify-content: Выравнивает сетку вдоль оси строки (inline). Значения:start,end,center,stretch,space-around,space-between,space-evenly.align-content: Выравнивает сетку вдоль оси столбца (block). Значения:start,end,center,stretch,space-around,space-between,space-evenly.place-content: Сокращение дляalign-contentиjustify-content. Например,place-content: center space-between;
CSS:
.container {
display: grid;
grid-template-columns: repeat(2, 100px); /* Общая ширина: 200px */
grid-template-rows: repeat(2, 100px); /* Общая высота: 200px */
width: 400px; /* Контейнер шире */
height: 400px; /* Контейнер выше */
gap: 10px;
background-color: #eee;
justify-content: center; /* Центрирует сетку по горизонтали внутри контейнера */
align-content: space-around; /* Распределяет дополнительное вертикальное пространство вокруг строк */
}
Адаптивные сетки: Увеличение возможностей с auto-fit/auto-fill и медиазапросами
Grid делает адаптивный дизайн намного проще.
auto-fit и auto-fill с minmax()
Эти ключевые слова, используемые с repeat() и minmax(), автоматически создают столько столбцов, сколько возможно, на основе минимальной ширины элемента, без необходимости в медиазапросах для количества столбцов.
auto-fill: Заполняет строку как можно большим количеством столбцов, даже если они пустые. Он создает треки для потенциально пустых ячеек.auto-fit: Работает какauto-fill, но если элементов меньше, чем доступных треков, он сворачивает пустые треки. Это заставляет элементы расти и занимать дополнительное пространство.
CSS:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* Столько столбцов, сколько может поместиться, каждый шириной не менее 200px и растущий, чтобы заполнить пространство */
gap: 1rem;
}
Эта одна строка CSS создает полностью адаптивную сетку. По мере изменения размера экрана количество столбцов будет автоматически регулироваться, а элементы будут расти или сжиматься в пределах своего диапазона minmax.
Комбинирование с медиазапросами
Для более резких изменений макета (например, совершенно разные структуры областей) медиазапросы по-прежнему необходимы.
CSS:
.container {
display: grid;
gap: 1rem;
grid-template-areas:
"header"
"sidebar"
"main"
"footer";
grid-template-columns: 1fr; /* Один столбец на маленьких экранах */
grid-template-rows: auto 1fr auto auto;
}
@media (min-width: 768px) {
.container {
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 1fr 3fr; /* Два столбца на средних экранах */
grid-template-rows: auto 1fr auto;
}
}
@media (min-width: 1200px) {
.container {
grid-template-areas:
"header header header"
"sidebar main content"
"footer footer footer";
grid-template-columns: 1fr 2fr 1fr; /* Три столбца на больших экранах */
grid-template-rows: auto 1fr auto;
}
}
Этот подход позволяет вам полностью переопределить структуру вашей сетки на разных точках разрыва, предлагая беспрецедентный контроль над адаптивными макетами.
CSS Grid против Flexbox: Когда использовать что?
Это распространенный вопрос для новичков. Ключевое отличие заключается в их размерности:
- CSS Grid: Предназначен для двумерных макетов (строки И столбцы одновременно). Идеален для общих макетов страниц, сложных секций или любых сценариев, где вам нужен точный контроль над элементами в обеих осях.
- CSS Flexbox: Предназначен для одномерных макетов (либо строки, ЛИБО столбцы). Идеален для распределения элементов в пределах одной строки или столбца, навигационных меню, внутренних макетов компонентов или простого распределения контента.
Они не являются взаимоисключающими! На самом деле, они прекрасно работают вместе. Вы можете использовать Grid для основного макета страницы, а затем использовать Flexbox внутри одного элемента сетки для организации его внутреннего контента.
Пример совместной работы Grid и Flexbox:
.page-container {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
height: 100vh;
}
.main {
grid-area: main;
display: flex; /* Flexbox применяется к элементу сетки */
flex-direction: column;
justify-content: space-between; /* Контент внутри 'main' будет распределен */
padding: 1rem;
}
.main-content {
/* ... стили для основного контента ... */
flex-grow: 1; /* Позволяет основному контенту занимать доступное пространство */
}
.main-actions {
/* ... стили для действий внизу основного ... */
}
Заключение
CSS Grid Layout — это невероятно мощный и универсальный инструмент, который революционизировал наш подход к веб-макету. Понимая его основные концепции — определение сеток, размещение элементов, использование единицы fr и использование grid-template-areas — вы можете создавать надежные, гибкие и по-настоящему адаптивные дизайны с меньшим количеством кода и большей ясностью.
Начните экспериментировать! Лучший способ изучить Grid — это строить вещи. Попробуйте воссоздать существующие макеты, которые вам нравятся, или создайте свои собственные с нуля. Вы быстро обнаружите радость и эффективность, которые CSS Grid приносит в веб-разработку.