CSS Grid – макет таблицы вернулся. Будь там и будь квадратным

ТЛ;ДР

Если вы знакомы с Flexbox, Grid должен показаться вам знакомым. Рэйчел Эндрю поддерживает отличный веб-сайт, посвященный CSS Grid, который поможет вам начать работу. Сетка теперь доступна в Google Chrome.

Флексбокс? Сетка?

За последние несколько лет CSS Flexbox стал широко использоваться, а поддержка браузеров выглядит очень хорошо (если только вы не один из бедняков, которым приходится поддерживать IE9 и ниже). Flexbox упростил множество сложных задач по макетированию, таких как равноудаленное расстояние между элементами, макеты сверху вниз или святой Грааль волшебства CSS: вертикальное центрирование.

Невозможно выровнять элементы в нескольких контейнерах flexbox.

Но, увы, у экранов обычно есть второе измерение, о котором нам нужно беспокоиться. К сожалению, если не позаботиться о размерах элементов самостоятельно, вы не сможете добиться одновременно вертикального и горизонтального ритма, просто используя только flexbox. Здесь на помощь приходит CSS Grid.

CSS Grid находился в разработке и использовался в большинстве браузеров уже более 5 лет , и дополнительное время было потрачено на совместимость, чтобы избежать ошибок при запуске, как это было с Flexbox. Поэтому, если вы используете Grid для реализации своего макета в Chrome, скорее всего, вы получите тот же результат в Firefox и Safari. На момент написания реализация Grid в Microsoft Edge устарела (такая же, как уже присутствовала в IE11), и обновление находится « на рассмотрении ».

Несмотря на сходство концепций и синтаксиса, не думайте о Flexbox и Grid как о конкурирующих методах компоновки. Grid размещается в двух измерениях, а Flexbox — в одном. При совместном использовании этих двух средств наблюдается синергия.

Определение сетки

Чтобы ознакомиться с отдельными свойствами Grid, я настоятельно рекомендую книгу Рэйчел Эндрю «Grid By example» или «Css Tricks Cheat Sheet» . Если вы знакомы с Flexbox, многие свойства и их значения должны быть вам знакомы.

Давайте посмотрим на стандартную сетку из 12 столбцов. Классический макет из 12 столбцов популярен, поскольку число 12 делится на 2, 3, 4 и 6 и поэтому полезно для многих дизайнов. Давайте реализуем этот макет:

Невозможно выровнять элементы в нескольких контейнерах flexbox.

Начнем с нашего кода разметки:

<!DOCTYPE html>
<body>
    <header></header>
    <nav></nav>
    <main></main>
    <footer></footer>
</body>

В нашей таблице стилей мы начинаем с расширения body , чтобы оно охватывало всю область просмотра, и превращения его в сеточный контейнер :

html, body {
    width: 100vw;
    min-height: 100vh;
    margin: 0;
    padding: 0;
}
body {
    display: grid;
}

Теперь мы используем CSS Grid. Ура!

Следующим шагом будет реализация строк и столбцов нашей сетки. Мы могли бы реализовать в нашем макете все 12 столбцов, но поскольку мы не используем каждый столбец, это сделало бы наш CSS излишне запутанным. Для простоты реализуем макет следующим образом:

Упрощенный пример планировки

Верхний и нижний колонтитулы имеют переменную ширину, а содержимое варьируется в обоих измерениях. Навигация также будет переменной в обоих измерениях, но мы собираемся установить для нее минимальную ширину 200 пикселей. (Почему? Разумеется, чтобы продемонстрировать возможности CSS Grid.)

В CSS Grid набор столбцов и строк называется треками . Начнем с определения нашего первого набора дорожек — строк:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
}

grid-template-rows принимает последовательность размеров, определяющую отдельные строки. В этом случае мы присваиваем первой строке высоту 150 пикселей, а последней — 100 пикселей. Для средней строки установлено auto , что означает, что она будет настроена на необходимую высоту для размещения элементов сетки (дочерних элементов контейнера сетки ) в этой строке. Поскольку наше тело растянуто на всю область просмотра, дорожка, содержащая контент (желтый на рисунке выше), как минимум заполнит все доступное пространство, но будет увеличиваться (и заставлять документ прокручиваться), если это необходимо.

Для столбцов мы хотим применить более динамичный подход: мы хотим, чтобы и навигация, и контент увеличивались (и уменьшались), но мы хотим, чтобы навигация никогда не уменьшалась ниже 200 пикселей, и мы хотим, чтобы контент был больше, чем навигация. В Flexbox мы бы использовали flex-grow и flex-shrink, но в Grid все немного по-другому:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
}

Мы определяем 2 столбца. Первый столбец определяется с помощью функции minmax() , которая принимает два значения: минимальный и максимальный размер этой дорожки. (Это похоже на min-width и max-width в одном.) Минимальная ширина, как мы обсуждали ранее, составляет 200 пикселей. Максимальная ширина — 3fr . fr — это единица измерения, специфичная для сетки, которая позволяет распределять доступное пространство по элементам сетки. fr, вероятно, означает «дробная единица», но вскоре может также означать свободную единицу . Наши значения здесь означают, что оба столбца вырастут, чтобы заполнить экран, но столбец содержимого всегда будет в 3 раза шире столбца навигации (при условии, что столбец навигации остается шире, чем 200 пикселей).

Хотя размещение элементов нашей сетки еще не правильное, размер строк и столбцов ведет себя правильно и дает то поведение, к которому мы стремились:

Размещение предметов

Одна из самых мощных функций Grid — возможность размещать элементы без учета порядка DOM. (Хотя, поскольку программы чтения с экрана перемещаются по DOM, мы настоятельно рекомендуем, чтобы они были должным образом доступны, и вы должны помнить о том, как вы меняете порядок элементов.) Если размещение вручную не выполняется, элементы размещаются в сетке в порядке DOM, располагаясь слева от вправо и сверху вниз. Каждый элемент занимает одну ячейку . Порядок заполнения сетки можно изменить с помощью grid-auto-flow .

Итак, как нам разместить элементы? Вероятно, самый простой способ разместить элементы сетки — определить, какие столбцы и строки они охватывают. Grid предлагает для этого два синтаксиса: в первом синтаксисе вы определяете начальную и конечную точки. Во втором вы определяете начальную точку и интервал:

header {
    grid-column: 1 / 3;
}
nav {
    grid-row: 2 / span 2;
}
Ручное размещение

Мы хотим, чтобы наш заголовок начинался в первом столбце и заканчивался перед третьим столбцом. Наша навигация должна начинаться со второй строки и охватывать в общей сложности 2 строки.

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

body {
    display: grid;
    grid-template-rows: 150px [nav-start] auto 100px [nav-end];
    grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
    grid-column: header-start / header-end;
}
nav {
    grid-row: nav-start / nav-end;
}

Приведенный выше код даст тот же макет, что и предыдущий код.

Еще более мощной является функция присвоения имен целым регионам в вашей сетке:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
    grid-template-areas: "header header"
                        "nav    content"
                        "nav    footer";
}
header {
    grid-area: header;
}
nav {
    grid-area: nav;
}

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

Есть ли еще?

Да, да, это слишком много, чтобы охватить одну публикацию в блоге. Рэйчел Эндрю , которая также является GDE , является приглашенным экспертом в рабочей группе CSS и с самого начала работала с ними, чтобы убедиться, что Grid упрощает веб-дизайн. Она даже написала об этом книгу . Ее веб-сайт Grid By example — ценный ресурс для знакомства с Grid. Многие считают, что Grid — это революционный шаг в веб-дизайне, и теперь он включен в Chrome по умолчанию, поэтому вы можете начать использовать его уже сегодня.