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

Далее рассмотрим, как работать с CSS Grid и как он помогает в процессе верстки.

Что такое CSS Grid

Это новая модель позиционирования элементов двумерных макетов. Она идеально подходит для всего, что требует отзывчивого позиционирования, в том числе и для создания адаптивных сайтов. CSS Grid чем-то похож на табличную верстку, которая активно использовалась в 90-е и начале 00-х годов. За основу страницы бралась таблица, разделенная на несколько колонок, которые наполнялись контентом. Однако HTML-таблицы создавалась для того, чтобы в них забивали данные, а не верстку, поэтому сайт, сделанный по такой схеме, выглядел не очень хорошо. Плюс, в то время не существовало потребности в адаптивном дизайне, поэтому сайт не мог корректно открываться иногда даже на экранах другого размера, не говоря про смартфоны.

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

Флоат – это основной компонент Grid-верстки. Он является свободно позиционируемым компонентом, за позицию которого отвечают собственные CSS-свойства, а также свойства других компонентов, с которыми он взаимодействует, например, родителя. Изначально планировалось остановиться только на внедрении флоатов, но оказалось, что они не всегда корректно работают во viewport-интерфейсах, то есть на большинстве мобильных устройств. Разработчики пытались исправить это с помощью разных “костылей”, которые со временем стали нормой и были доработаны. Так окончательно появился современный CSS Grid.

Grid Layout позволяет за более короткое время и с меньшим количеством кода решать те задачи, на которые в обычном случае уходило бы больше времени, требовалось бы писать больше кода и иногда пользоваться нестандартными решениями, которые не добавляют стабильности работы. Благодаря поддержки работы в двух измерениях есть возможность создавать более сложные и комплексные шаблоны.

Как работает Grid CSS

В основе лежит система сеток из набора пересекающихся горизонтальных и вертикальных линий. В итоге весь шаблон разделяется на блоки – контейнеры, которые в свою очередь можно поделить на дополнительные контейнеры и спозиционировать их относительно друг друга. Для создания грид-разметки вам требуется прописать в CSS-свойствах к компоненту display: grid. После этого все элементы, находящиеся внутри этого блока станут grid-элементами и будут позионироваться по соответствующим правилам. Для всех новых компонентов, которые будут добавляться в этот блок вы сможете задавать grid-свойствах для их позиционирования относительно друг друга внутри родителя.

Для начала нужно определиться, сколько колонок будет внутри родительского элемента. Их количество можно задать фиксированное, а можно сделать так, чтобы оно менялось в зависимости от размещаемого внутри контента. Размер ячеек обычно не фиксированный и меняется в зависимости от того, что находится внутри них. Ячейки можно объединять между собой, вытеснять другие ячейки на следующие столбцы.

Верстка с использованием CSS Grid Layout

Далее на нескольких примерах рассмотрим подобрано все особенности разработки с использованием Grid-компонентов. Для удобства разделим процесс на несколько этапов.
Создание Grid-элементов
Для начала создадим грид-таблицу внутри одного из элементов. Размеры ячеек оставим по умолчанию, но сделаем между ними отступы. Вот так будет выглядеть CSS-разметка:

В итоге, вы получите сетку 3x3 блока, если смотреть на обычном разрешении. Между ячейками будет небольшой отступ, размер которого будет адаптироваться к изменению размера экрана. Если уменьшить размер экрана, то блоки начнут занимать не ⅓ от размера строки родителя, а 100%.

Пример простой Grid-сетки

В HTML-разметке писать что-то дополнительно не нужно – достаточно задать класс, к которому будут применяться стили, поэтому разберем подробно, какие свойства были написаны в CSS и за что они отвечают:

  • display: grid. Отвечает за превращение родительского элемента в грид-контейнер. Теперь к нему и вложенным компонентам можно применять другие grid-стили. По умолчанию у контейнера будет такое же поведение, как и у любого блочного элемента. Вы можете изменить его, приписав соответствующую приставку, например, display: inline-grid. В таком случае будет создан строчный грид-контейнер с соответствующим поведением.
  • display: subgrid. Этого свойства не было в примере выше, но его тоже стоит рассмотреть. Оно отвечает за создание подсетки, например, внутри вложенного элемента.
  • grid-template-rows: 1fr 1fr 1fr. Задает размер рядов в grid-системе и их позиционирование. Единица измерения fr позволяет подстраивать размер ячеек под контент внутри них и внешние элементы, плюс, учитывать дополнительные условия. В нашем примере пространство распределяется равномерно, но вы можете сделать так, чтобы какой-то конкретной ячейке давалось больше пространства, указав не 1fr, а 2. Кстати, тут можно указывать и нецелые значения – 4.5, 5.2 и подобные. Если по каким-то причинам не подходит единица измерения fr, то можно указать %, em или даже фиксированную величину в пикселях, однако fr дает наилучший результат.
  • grid-template-columns: 1fr 1fr 1fr. Аналогично с предыдущим пунктом, но только здесь задается размер колонок.
  • grid-gap: 2vw. Задает отступы между колонками сверху, снизу и по бокам. Единицы измерения тоже можно задать любые – хоть %, хоть пиксели. Если нужно задать отступ сбоку, то используйте свойство grid-row-gap, а если сверху и снизу, то grid-column-gap.

Это были основные параметры, отвечающие за позиционирование грид-сетки. Для 80% задач, выполняемых средним верстальщиком, их будет достаточно. Второй блок кода в примере отвечает за стилизацию ячеек. Ничего, связанного с Grid Layout в нем нет.

Пример шаблона сайта на Grid

Разобравшись с основными свойствами и понятиями грид-верстки, попробуем создать шаблон страницы сайта как на картинке ниже. Это примитивный и универсальный шаблон, проблем с которым не должно возникнуть.

Пример Grid-шаблона

У CSS Grid очень простой синтаксис, позволяющий “видеть” выстраивание шаблона в коде, хотя для этого потребуется некоторая практика. Создание шаблонов любой сложности в таком случае станет пустяковым делом. Вот примерно такой CSS-код должен получится:

Здесь грид-контейнером был сделан весь тег body, то есть все содержимое страницы уже приобретает грид-свойства, следовательно, их можно к ним применять. В целом, в этом примере большинство свойств уже рассматривались в первом примере с ячейками. Внимание нужно обратить на grid-template-areas, так как это свойство не рассматривалось ранее и логика его работы отличается от других.

Он определяет наш шаблон. Если же мы посмотрим на код, то увидим, что это 3х3 таблица (три ряда и три колонки). Это означает, что у нас получается пять грид-областей на девяти грид-ячейках. Обратите внимание, что некоторые грид-области занимают несколько ячеек. Например, шапка, занимает весь первый ряд из трех ячеек. Аналогичное пространство занимает подвал, но только в нижней части. Панель с навигацией и рекламой занимают по одной ячейки, но при этом их размер меньше, чем у центральной ячейки, под которую отведена секция с основным контентом.

Так вот, свойство grid-template-areas позволяет определить для каждого элемента свою область. Она была определена в кавычках: "header header header", “nav article ads” и “footer footer footer”. Затем с помощью свойства grid-area происходит задание элементам области:

Также обратим внимание на задание размеров:

  • grid-template-rows: 60px 1fr 60px – первая и третья строки будут обе по 60 пикселей фиксировано. Вторая строка заберет все оставшееся место.
  • grid-template-columns: 20% 1fr 15% – отвечает за размер столбцов. Первый 20% от общего размера, третий 15%, а центральный занимает все оставшееся место.

Корректируем шаблон

Готовый шаблон легко меняется посредствам перераспределения грид-областей в свойстве grid-template-areas. Для примера внесем такие изменения:

grid-template-areas:
  "nav header header"
  "nav article ads"
  "nav footer ads";

Вот пример того, каким получился шаблон. Размеры регулируются в свойствах grid-template-rows и grid-template-columns. В итоге, просто меняя значения в кавычках можно изменить расположение компонентов в шаблоне – все очень просто.

Шаблон после корректировки

Задание адаптивности

Имеющийся шаблон уже умеет подстраиваться под изменения размеров экрана, но полностью адаптивным его назвать трудно, так как на мобильных он все равно отображается не совсем корректно. Исправить это можно с помощью значений auto-fill и auto-fit. С их помощью создаются специальные треки, меняющие параметры элементов в зависимости от размера экрана.

Для начала рассмотрим пример с auto-fill:

grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));

В нем колонкам присваивается минимальный размер в 150px и максимальный по оставшемуся месту. Они будут повторяться столько раз, сколько необходимо для того чтобы уложиться в заданный контейнер. В случае с параметром auto-fill ячейки подстраиваются таким образом, чтобы полностью заполнить контейнер. В примере минимальный размер ячейки 150 пикселей, а максимальный 1fr.

Auto-fit практически не отличается от auto-fill. Разница между ними только в том, что стягиваются все пустые треки на конце размещения. Fit просто растягивает контейнер таким образом, чтобы не оставалось пустого места, не считая заранее заданных отступов.

Различия между fit и fill

Использование медиа-запросов

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

Вот пример адаптации шаблона под экраны телефонов:

Если разрешение экрана будет меньше 575 пикселей, то все ячейки будут занимать один столбец полностью и выстроятся друг за другом в том порядке, который указан в свойстве grid-template-areas. Еще обратите внимание, что в grid-template-columns теперь только один размер.

Концепция явного и неявного грида

С этой концепцией нужно быть знакомым. В противном случае вы можете столкнуться с несколькими лишними колонками и не понимать, откуда они взялись. Вот определения:

  • Явный грид это тот, который вы сами задали с помощью свойств grid-template-rows, grid-template-colums и grid-template-areas.
  • Неявные гриды – это те, которые не уместились в вашу заданную сетку. Вы определили грид который может уместить только шесть элементов, но сам контейнер состоит из девяти элементов. В явный грид войдут только шесть элементов, а еще три станут неявными.

Явный и неявный грид

Создание вложенных ячеек

Грид-ячейка может тоже быть родителем для других ячеек. Они будут наследовать ее свойства. Для того, чтобы создать вложенный контейнер просто укажите в его CSS свойствах display: grid или его производные. Распределение пространства внутри будет происходить по тому же принципу, что в обычном грид-контейнере.

Создание вложенных гридов

Наследование

Наследуются только самые основные свойства. Обычно это только размер и количество колонок – оно по умолчанию будет таким же как в контейнере-родителе. Отсутствие расширенного наследования объясняется желанием минимизировать влияние вложенного грида на основной. Это позволяет избежать “поломки” верстки, но не очень удобно тем, что нужно прописывать все свойства повторно.

Заключение

Мы рассмотрели только азы CSS Grid Layout. Этого достаточно, чтобы верстать адаптивные шаблоны для большинства сайтов. Освоить эту технологию очень просто, если вы знаете CSS на базовом уровне – достаточно выучить несколько дополнительных свойств и параметров к ним.