От автора: я помню, как впервые изучал CSS, и как я был рад узнать о display float и inline, которые позволяют размещать элементы, как нам нужно. Интересно, как бы я отреагировал, если бы в то время была доступна система двумерного макета? На самом деле, даже сейчас я взволнован этим, потому что это меняет все: как способ написания CSS, так и способ, которым мы пишем разметку. С помощью CSS Grid проще, чем когда-либо, создавать адаптивные, динамические и независимые от исходного формата макеты.
В этом посте мы узнаем обо всех свойствах CSS Grid для создания простых и более сложных макетов. Мы сначала рассмотрим основы, а затем копнем немного глубже, чтобы увидеть, чего мы можем достичь с помощью CSS Grid. С учетом вышесказанного, если вы готовы научиться новому подходу к проектированию, возьмите красную таблетку, и я покажу вам, насколько глубока кроличья нора.
1. Прежде чем мы начнем
Но прежде чем мы начнем, я хотел бы рассмотреть некоторые проблемы, которые могут у вас возникнуть, а также убедиться, что вы знакомы с основами CSS Grid и ее терминологией.
Вопросы и ответы
CSS Grid заменяет flex-box?
Что ж, CSS Grid не заменяет flex-box. Это два разных инструмента для разных целей. На самом деле, они очень хорошо работают вместе, у нас может быть flex внутри сетки и наоборот.
Каковы различия между CSS Grid и flex-box?
Различий много, но главное в том, что flex-box — это система одномерного макета, а CSS-сетка — это система двумерного макета. Посмотрите на рисунок 1.1 ниже:
Рисунок 1.1: Flex-box и CSS Grid
Почему не использовать вместо этого bootstrap?
Я думаю, что лучший ответ на этот вопрос — цитата Джен Симмонс: Чем больше я использую CSS Grid, тем больше я убеждаюсь в том, что никакой дополнительной выгоды от того, чтобы добавить дополнительный слой абстракции, не будет. CSS Grid — это структура макета, встроенная прямо в браузер — Джен Симмонс
Готова ли CSS-сетка уже к работе?
По-разному. Нужна ли вам поддержка: IE, Opera mini, Blackberry browser или Baidu mobile? Если ответ « нет», то да, она готова к работе, если ответ «да», вы в любом случае можете использовать ее для браузеров, которые ее поддерживают (без префикса: 91,61%), используя правило CSS @supports:
1 2 3 4 5 |
@supports (display: grid) { div { display: grid; } } |
Основы
В принципе, сетка может быть разбита на два элемента: grid-контейнер и grid-элементы.
Рисунок 1.2: Основные элементы сетки
Как мы видим на рисунке 1.2, контейнер сетки представляет собой набор колонок и рядов. row или ряд — это пространство между двумя последовательными горизонтальными линиями, а column или колонка — это пространство между двумя последовательными вертикальными линиями. Ряд можно назвать треком, и то же самое относится и к колонке. Таким образом, трек сетки — это пространство между двумя параллельными линиями сетки.
Каждый трек может содержать одну или несколько ячеек сетки. Ячейка сетки является основной наименьшей единицей сетки. Это пространство между четырьмя пересекающимися линиями сетки. Если мы объединим несколько ячеек сетки вместе, мы получим область сетки. Важно отметить, что область сетки должна быть прямоугольной, например, у нас не может быть Т-образной области сетки.
Ряды сетки начинаются с 1 до количества рядов, которые вы явно или неявно определили. Номер последнего ряда сетки может указываться как -1, ряд сетки перед ним как -2 и так далее. Мы рассмотрим подробнее это позже.
На рисунке 1.2 количество линий колонок изменяется от 1 до 6 (от -6 до -1), а количество линий рядов — от 1 до 5 (или от -5 до -1).
Количество линий сетки считается явным, если вы явно установите его в CSS. И неявным, если оно установлено браузером динамически. Наконец, ячейки сетки могут быть разделены отступами. Эти отступы называются зазорами.
2. Основные свойства CSS сетки
Хорошо, теперь мы должны быть готовы начать реализацию некоторых сеток. Сначала мы поговорим обо всех свойствах, которые мы могли бы использовать с контейнером сетки, затем рассмотрим свойства элементов сетки. Давайте рассмотрим следующий шаблон для этого раздела:
1 2 3 4 5 6 7 8 9 10 11 |
<div class="grid-container"> <div class="grid-item">grid item 1</div> <div class="grid-item">grid item 2</div> <div class="grid-item">grid item 3</div> <div class="grid-item">grid item 4</div> <div class="grid-item">grid item 5</div> <div class="grid-item">grid item 6</div> <div class="grid-item">grid item 7</div> <div class="grid-item">grid item 8</div> <div class="grid-item">grid item 9</div> </div> |
Контейнер сетки
display
Сетка CSS определяется с помощью значения grid для свойства display. Итак, чтобы определить сетку, используя шаблон выше, мы должны сделать это:
1 2 3 |
.grid-container { display: grid; } |
Ряды и колонки
Мы можем определить колонки и ряды сетки, используя свойства grid-template-rows и grid-template-columns:
1 2 3 4 |
.grid-container { grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-rows: 1fr auto 2fr; } |
Или мы можем использовать grid-template, в котором сначала определяем grid-template-rows, а затем grid-template-columns (разделенные косой чертой):
1 2 3 |
.grid-container { grid-template: 1fr auto 2fr / 1fr 1fr 1fr 1fr; } |
Кстати, fr это дробная единица, то есть 1fr — это 1 часть доступного пространства.
Функция repeat
Функция repeat() представляет собой повторяющееся фрагмент. Таким образом, мы могли бы получить тот же шаблон, что и выше, например, так:
1 2 3 |
.grid-container { grid-template: 1fr auto 2fr / repeat(4, 1fr); } |
Ознакомьтесь с документацией, чтобы узнать, как использовать auto-fit и auto-fill, чтобы добавлять треки динамически.
Функция Minmax
Функция CSS minmax() определяет диапазон размеров, больший или равный минимальному и меньший или равный максимальному. Мы можем использовать это с repeat() так:
1 2 3 |
.grid-container { grid-template-columns: repeat(3, minmax(100px, 1fr)); } |
Зазоры
Мы можем добавить зазоры между линиями рядов, используя row-gap, мы можем сделать то же самое между линиями колонок, используя column-gap:
1 2 3 4 |
.grid-container { row-gap: 5px; column-gap: 10px; } |
Или мы можем использовать gap, где мы сначала определяем row-gap, а затем column-gap:
1 2 3 |
.grid-container { gap: 5px 10px; } |
Если зазор для колонок такой же, как для рядов, мы можем указать только одно значение.
Элементы сетки
Чтобы указать начальную и конечную позицию элемента сетки внутри сетки, мы в основном используем четыре свойства. Давайте посмотрим на их определения.
grid-row-start. CSS-свойство grid-row-start определяет начальную позицию элемента сетки в ряду сетки, добавляя ряд, интервал или ничего (автоматически)
grid-row-end. CSS-свойство grid-row-end указывает конечную позицию элемента сетки в строке сетки, добавляя строку, интервал или ничего (автоматически)
grid-column-start. Свойство CSS grid-column-start определяет начальную позицию элемента сетки в столбце сетки, добавляя строку, интервал или ничего (автоматически)
grid-column-end. Свойство CSS grid-column-end указывает конечную позицию элемента сетки в столбце сетки, добавляя линию, интервал или ничего (автоматически)
Или мы можем использовать сокращенную версию этих свойств:
grid-row. CSS-свойство grid-row является сокращенным свойством для grid-row-start и grid-row-end, определяющим размер и расположение элемента сетки в строке сетки.
grid-column. CSS-свойство grid-column является сокращенным свойством для grid-column-start и grid-column-end, определяющим размер и расположение элемента сетки в столбце сетки.
Пространство базового шаблона
Итак, учитывая разметку, которую мы имеем в начале этого раздела, скажем, мы хотим, чтобы третий элемент сетки занимал 4 ячейки вместо одной (мы хотим, чтобы он охватывал два столбца сетки и две строки), как показано на рисунке 1.3. Как мы можем это сделать?
Рисунок 1.3: Пример пространств шаблона
Мы могли бы реализовать это так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Grid container .grid-container { display: grid; gap: 10px; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(3, 1fr); } // Grid item (third) .grid-container .grid-item:nth-child(3) { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 3; // or grid-column: 1 / 3; grid-row: 1 / 3; // or grid-column: 1 / span 2; grid-row: 1 / span 2; // or grid-column: -5 / span 2; // because we have 4 columns grid-row: -4 / span 2; // because we have 3 rows } |
Обратите внимание, что третий элемент сетки фактически является первым на рисунке 1.3. Это связано с тем, что с помощью CSS-сетки мы можем (впервые) получить независимость от исходного порядка. Мы коснемся этого чуть позже, когда будем говорить о grid-auto-flow.
Перейдите сюда, если вы хотите поэкспериментировать и изучить различные решения.
3. Продвинутые шаблоны
Есть более продвинутые свойства, которые могут помочь вам настроить шаблон так, как вам бы хотелось. В этом разделе мы рассмотрим эти свойства и посмотрим, как мы можем использовать их в коде CSS. Для этого раздела рассмотрим следующий шаблон:
1 2 3 4 5 6 7 |
<div class="grid-container"> <div class="grid-item header">Header</div> <div class="grid-item content">Content</div> <div class="grid-item navbar">Navbar</div> <div class="grid-item meta">Meta</div> <div class="grid-item footer">Footer</div> </div> |
Используя то, что мы узнали раньше, мы можем добавить следующий CSS, чтобы он выглядел как базовый макет сайта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.grid-container { grid-template: repeat(6, 1fr) / repeat(12, 1fr);// rows then columns } .grid-container .header { grid-column: 1 / -1; grid-row: 1 / 2; } .grid-container .navbar { grid-column: 1 / 2; grid-row: 2 / -1; } .grid-container .content { grid-column: 2 / -1; grid-row: 2 / -2; } .grid-container .footer { grid-column: 2 / -1; grid-row: -2 / -1; } .grid-container .meta { grid-column: -3 / -1; grid-row: 2 / 4; } |
Рисунок 1.4: Базовый макет сайта. Код доступен здесь
Теперь предположим, что мы хотим, чтобы navbar (справа) был немного шире. На данный момент он охватывает один ряд колонки, вместо этого мы хотим, чтобы он охватывал две колонки. Для этого мы можем изменить положение .navbar, но нам также нужно изменить позицию .content и.footer, потому что в настоящее время .navbar размещается между линиями рядов 1 и 2, а .footer и .content начинаются от линии колонки 2 и до последней.
Утомительно менять положение элементов, если бы нам приходилось делать это каждый раз, было бы здорово, если бы был способ заставить CSS-сетку делать это автоматически. Ну, есть не один, а целых два способа.
Именованные строки
Первое решение — назвать конкретную строку, затем сослаться на нее, используя ее псевдоним вместо номера. Давайте попробуем реализовать это.
1 2 3 4 |
.grid-container { grid-template-rows: repeat(6, 1fr); grid-template-columns: 1fr 1fr [content-start navbar-end] repeat(10, 1fr); } |
В приведенном выше коде мы назвали третий ряд, используя квадратные скобки с псевдонимами внутри (один ряд может иметь несколько псевдонимов). Тогда теперь мы изменим CSS элементы, упомянутые ранее:
1 2 3 4 5 6 7 8 9 |
.grid-container .navbar { grid-column: 1 / navbar-end; grid-row: 2 / -1; } .grid-container .content { grid-column: content-start / -1; grid-row: 2 / -2; } .grid-container .footer { grid-column: content-start / -1; grid-row: -2 / -1; } |
Результат должен выглядеть так:
Рисунок 1.5: Базовый макет сайта — расширенная панель навигации
Попробуйте сделать то же самое для других строк (например: header-row-end / content-row-start) в этом фрагменте кода.
grid-template-areas
Второе решение состоит в использовании областей шаблона. Свойство CSS grid-template-areas определяет именованные области сетки. Это свойство имеет странный для CSS синтаксис, но мы используем его так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
.grid-container { grid-template-areas: 'h h h h h h h h h h h h' 'n n c c c c c c c c c c' 'n n c c c c c c c c c c' 'n n c c c c c c c c c c' 'n n c c c c c c c c c c' 'n n f f f f f f f f f f'; } .grid-container .navbar { grid-area: n; } .grid-container .content { grid-area: c; } .grid-container .footer { grid-area: f; } .grid-container .header { grid-area: h; } .grid-container .meta { grid-column: -3 / -1; grid-row: 2 / 4; } |
Мы используем grid-template-areas, чтобы определить области контейнера сетки, затем мы помещаем элементы сетки в желаемую область, используя grid-area. Напоминаем, что все области должны быть прямоугольными.
Обратите внимание на то, что мы не использовали grid-area для элемента .meta. Это потому, что пока нет способа накладывать элементы один на другой с помощью этого метода. По крайней мере, я такого не знаю. Вы можете поэкспериментировать с этим макетом, код доступен здесь.
4. Неявные строки и поток сетки
Давайте рассмотрим следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<div class="grid-container"> <div class="grid-item">1</div> <div class="grid-item">2</div> <div class="grid-item">3</div> <div class="grid-item">4</div> <div class="grid-item">5</div> <div class="grid-item">6</div> </div> <style> .grid-container { grid-template-columns: repeat(3, minmax(100px, 1fr)); grid-template-rows: 80px; } .grid-container .grid-item:nth-child(2) { grid-row: span 2; } .grid-container .grid-item:nth-child(3) { grid-column: span 3; } </style> |
У нас есть сетка из трех столбцов, и мы хотим, чтобы второй элемент сетки охватывал две строки, а третий — три столбца:
Рисунок 1.6 Плохо выглядящая сетка
Это выглядит плохо, так что же здесь происходит? Во-первых, второй элемент немного выше первого, потому что мы сказали, что он в два раза выше, но совсем не выглядит в два раза выше. Кроме того, элементы сетки от 3 до 6 имеют меньшую высоту, чем первый.
Неявные строки
Это связано с тем, что мы явно установили первый ряд: grid-template-rows: 80px;. Но другие ряды были созданы неявно, поэтому второй ряд почти не видно, потому что он пуст, а остальные ряды настолько велики, насколько необходимо для их содержимого.
Мы могли бы исправить это, установив высоту неявно созданных рядов, используя grid-auto-rows так:
1 2 3 4 5 |
.grid-container { grid-template-columns: repeat(4, minmax(100px, 1fr)); grid-template-rows: 80px; grid-auto-rows: 100px; } |
И это должно выглядеть так:
Рисунок 1.7 Уже лучше, но все же
Это выглядит лучше, но, тем не менее, мы можем сделать еще лучше. Обратите внимание на пустые места, почему бы нам не использовать их для размещения элементов сетки 4, 5 и 6? Для этого мы можем использовать grid-auto-flow.
Поток сетки
Свойство CSS grid-auto-flow управляет работой алгоритма автоматического размещения, точно определяя, как автоматически размещаемые элементы расставляются в сетке. Это можно сделать с помощью нескольких параметров, но сейчас нас интересует только один: dense. Он указывает браузеру разместить элементы на достаточно большом для них месте:
1 2 3 |
.grid-container { grid-auto-flow: dense; // default is row } |
Теперь наша сетка наконец выглядит красиво.
Рисунок 1.8 Правильно реализованная сетка
Заключение
Это довольно много информации, но мы рассмотрели многие свойства CSS-сетки, поэтому вы должны чувствовать себя достаточно уверенно, чтобы начать использовать CSS-сетку в своих приложениях. Этот пост является первым из серии, в следующем мы будем реализовывать 3 практических примера с использованием сетки, так что следите за новостями. Я надеюсь, что вы узнали что-то полезное и, как всегда, удачного кодирования!
Автор: Mustapha
Источник: //dev.to
Редакция: Команда webformyself.