Введение в CSS Grid
18.03.2017

Введение в CSS Grid

Оригинал: Getting Started with CSS Grid, Robin Rendle

Это была насыщенная неделя для разработчиков интерфейсов, поскольку CSS Grid попал в последние версии Firefox и Chrome без флага. Правильно: теперь мы можем пойти и поиграться с Grid в двух самых популярных браузерах.

Но почему CSS Grid имеет большое значение?

CSS Grid — первая реальная система построения сеток. Она предназначена для размещения контента как в столбцах, так и в строках, и, наконец, дает разработчикам почти неограниченный контроль над элементами на экране. Это означает, что мы можем, наконец, избавиться от многолетних хаков и обходных решений для размещения элементов на веб-странице — в конечном счете это означает, что сложные макеты теперь не только возможно реализовывать, но и легко поддерживать.

С помощью CSS Grid веб станет гораздо более красивым, чем то, к чему мы привыкли.

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

Для начала добавим разметку:


<div class='wrapper'>
  <div class='letter'>
    A
  </div>
  <div class='letter'>
    B
  </div>
</div>

Стилизуем эти буквы с помощью свойств font-size и color и центрируем в блоке с помощью свойств flexbox align-items и justify-content. И да, это правильно! CSS Grid не заменяет свойства flexbox, он дополняет то, что они уже делают. Мы можем использовать многие из этих свойств в сочетании с CSS Grid. Но сейчас вернемся к демонстрации:

В примере выше у нас есть два простых div’а, расположенных друг под другом, потому что они по умолчанию — display: block. Установим для родительского элемента display: grid:


.wrapper {
    display: grid;
}

Это приведет к следующему:

--- DEMO ---

Вы можете увидеть, что ничего не произошло. И вы будете правы! В отличие от display: inline-block; или display: inline; не совсем ясно, что происходит, когда мы устанавливаем свойство display в grid. Фактически, чтобы заставить нашу сетку что-то делать, нам сначала нужно задать ей определенное количество столбцов или строк. Выровняем буквы рядом друг с другом в два столбца:

See the Pen Type Specimen Grid Demo – 1 by Robin Rendle (@robinrendle) on CodePen.


.wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-column-gap: 1px;
    background-color: black;
}

Давайте разберем эти новые строки кода. Сначала мы создаем два столбца нашей сетки с помощью grid-template-columns. Значение 1fr может показаться странным, если вы никогда его раньше не видели, но это валидная единица измерения в CSS, которая сообщает каждой колонке, что она будет занимать одну часть сетки. В нашем случае это означает, что сетка будет иметь два столбца равной ширины.

See the Pen Type Specimen Grid Demo – 2 by Robin Rendle (@robinrendle) on CodePen.

Ура! Оно работает. Видите небольшой зазор между буквами? Это цвет фона, выглядывающий из-под блоков, поскольку мы задали значение свойства grid-column-gap 1px. Обычно задается больший зазор, особенно, для текстовых блоков, но в нашем случае достаточно и одного пикселя.

А что произойдет, если добавить две новые буквы в разметку? Как это изменит страницу?


<div class='wrapper'>
  <div class='letter'>
    A
  </div>
  <div class='letter'>
    B
  </div>
  <div class='letter'>
    C
  </div>
  <div class='letter'>
    D
  </div>
</div>

Ну, технически это не изменит сетку — мы уже сказали, что она будет иметь две колонки, поэтому новые буквы будут расположены под ними.

See the Pen Type Specimen Grid Demo – 3 by Robin Rendle (@robinrendle) on CodePen.

Странная вещь — почему нет зазора в 1px между буквами A и C или между B и D? Все правильно, свойство grid-column-gap устанавливает зазор только между столбцами. Чтобы исправить это, можно добавить свойство grid-row-gap:


.wrapper {
    grid-column-gap: 1px;
    grid-row-gap: 1px;
    /* прочие стили */
    /* можно использовать сокращение ‘grid-gap’ */
}

Теперь наш пример выглядит так:

See the Pen Type Specimen Grid Demo – 4 by Robin Rendle (@robinrendle) on CodePen.

Мы создали нашу первую сетку. Но давайте просто изучим наши колонки немного подробнее. Что произойдет, если мы добавим другое значение в свойство grid-template-columns? Например:


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

Ну, добавится еще одна колонка, конечно же! Обратите внимание, как мы теперь можем четко видеть фон обертки, потому ничто не закрывает его:

See the Pen Type Specimen Grid Demo – 5 by Robin Rendle (@robinrendle) on CodePen.

Если мы изменим значение fr в свойстве grid-template-columns, это создаст так называемую асимметричную сетку. Предположим, что мы бы хотели, чтобы наш первый столбец занимал втрое больше места, чем два других столбца:


.wrapper {
    grid-template-columns: 3fr 1fr 1fr;
}

Столбцы A и D стали шире остальных столбцов, как и ожидалось:

See the Pen Type Specimen Grid Demo – 6 by Robin Rendle (@robinrendle) on CodePen.

Разве это не мощно? Больше не нужно беспокоиться об отрицательных отступах или идеальных значениях в процентах, чтобы выровнять колонки. Мы можем создавать суперсложные сетки без необходимости делать какие-либо математические вычисления, которые мы были вынуждены делать раньше. Теперь нам просто нужно добавить новое значение в свойство grid-template-columns и вуаля, новый столбец появляется как по волшебству!

Но как насчет адаптивных сеток, спросите вы? Это действительно так же просто, как изменить свойство в медиа-запросе. Предположим, что мы хотим по умолчанию видеть 2 столбца, на экранах больше 500 пикселей мы хотим 3 столбца, и, наконец, на больших экранах мы разместить все содержимое в 4 столбца. Все, что нам нужно написать, это:


.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr;
  
  @media screen and (min-width: 500px) {
    grid-template-columns: 1fr 1fr 1fr;
  }
  
  @media screen and (min-width: 800px) {
    grid-template-columns: 1fr 1fr 1fr 1fr;
  }
}

Откройте демо в отдельной вкладке и убедитесь, что адаптивная магия работает!

Свойство grid-template-columns намного сложнее, чем показано здесь, но и это отличная отправная точка. Далее мы должны подробнее познакомиться с другим важным свойством в спецификации CSS Grid: grid-template-rows.

Хорошо, давайте сделаем это. Ниже приведен небольшой фрагмент кода. С учетом того, что вы раньше не сталкивались с CSS Grid, попробуйте догадаться, что делает свойство grid-template-rows:


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

Это свойство устанавливает высоту строк и их взаимосвязь друг относительно друга. Если у нас есть две строки, как в нашем предыдущем демо, а последний блок установлен в 3fr, это означает, что высота второй строки всегда будет в три раза больше высоты первой:

See the Pen Type Specimen Grid Demo – 8 by Robin Rendle (@robinrendle) on CodePen.

Это может выглядеть довольно просто, но раньше мы не могли этого сделать. Нам приходилось писать хаки, такие как установка минимальной высоты для определенного элемента или изменение имени класса. Но мы никогда не могли задать отношения между строками; вот что делает CSS Grid таким мощным.

Даже благодаря такому небольшому количеству знаний и нескольким новым свойствам мы можем создавать сказочно сложные макеты — асимметричные и адаптивные сетки — это еще не все.

Весь код в примерах выше выглядит на первый взгляд очень странно. Но с ним теряют актуальность и гигантские CSS-фреймворки, и целый набор старых хаков. CSS Grid позволяет нам взглянуть на пространство внутри браузера совершенно по-новому.

Нам придется изучить кучу новых свойств и полностью переосмыслить то, что мы знали раньше. Поэтому CSS Grid — это не только спецификация, а целая философия.

Давайте разбираться вместе!