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

Разница между Flex и Grid

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

Первое, что бросается в глаза – зазоры между блоками – gap. Это фишка чисто CSS Grid, хотя что-то похожее появилось и во Flexbox. Правда, реализация гапов во флексах немного отличается, что может создавать небольшие неудобства, особенно разработчикам, привыкшим с ними работать.

Но фундаментальное различие между флексами и гридами кроется в размерностях. Флексы одномерные, а гриды двумерные. Это значит, что флекс-элемент сложнее передвигаться по плоскости – управлять расположением элементов в рядах не получится без “костылей”. С гридами таких проблем нет – элементы легко могут передвигаться между рядами, занимать по несколько столбцов.

Рассмотрим пример:

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

flex-direction: column;

Грид разметка же работает по табличной разметке. Это значит, что один элемент вполне может занимать не только размер в строках, но и в столбцах. Очень удобно для создания отзывчивых интерфейсов. Однако работа с двумя измерениями накладывает определенные трудности, например, не получится одним свойством сделать переориентацию всех элементов по вертикали, особенно, если один из них занимает несколько столбцов.

Наглядная демонстрация различий между Flexbox и Grid

Что и когда лучше выбрать

Кроме обозначенных, других отличий между Grid и Flexbox нет. Начинающему разработчику может быть сложно определиться с выбором, так как оба варианта, в целом, позволяют добиться одинакового результата. К тому же, часто оба варианта разметки совмещаются в одном макете. Это еще сильнее запутывает начинающих разработчиков.

Самое первое, что вы должны сделать, чтобы определиться, что именно использовать, задать себе такие вопросы:

  • Какое должно быть расположение элементов? По одной строке, столбцу или в рамках некой сетки? В последнем случае однозначно выбирайте Grid.
  • Какое поведение должно быть на разных размерах экрана? Флексы более отзывчивы.
  • Как будут выстраиваться дочерние компоненты? Если они выстраиваются внутри родителя по одной оси, то лучше выбирать флексы.

Для лучшей наглядности рассмотрим несколько примеров интерфейсов и узнаем, почему лучше выбирать для них то или иное решение.

Разделение страницы на боковую область и основную

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

Пример разделения страницы на два блока

У примера выше будет очень примитивная HTML-разметка, поэтому подробно рассматривать ее нет смысла. Вот она:

А вот CSS-код стоит рассмотреть подробнее:

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

Набор карточек

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

Здесь размер карточек выставляется автоматически, в зависимости от размера родителя, но он не может быть менее 200 пикселей в ширину.

Пример с карточками

Однако, если вам нужно расположить карточки не сеткой, а по какой линии, например, для слайдера, то тут лучше будет выбрать Flexbox.

Элементы со сложной структурой

Рассмотрим для примера вот эту форму обратной связи:

Сложная форма обратной связи

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

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

Навигационные панели

А вот здесь уже практически всегда оптимальным вариантом будет Flexbox. Дело в том, что практически всегда навигационная панель это блок, выстроенный в одну линию. Это касается даже сложных меню, где присутствует несколько уровней – просто каждый уровень будет отдельной строкой.

Для примера рассмотрим простой блок меню, в котором есть логотип, несколько пунктов и кнопка. При этом между логотипом и основным меню должно оставаться определенное пространство.

Пример навигационной панели

Вот как это реализуется с помощью CSS Flex:

Обратите внимание на свойство justify-content. С его помощью происходит настройка расстояния между элементами внутри основного блока. В рассматриваемом случае указан space-between, поэтому элементы прикреплены к противоположным краям основного блока.

Заголовки

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

Пример заголовка модального окна

Реализуется подобная задумка так:

Свойство justify-content: space-between разносит элементы заголовка по противоположным сторонам. Вы можете изменить его, если вам нужно добиться какого-то другого эффекта. Например, в заголовке к основной статье управляющие элементы могут быть приближены вплотную к тексту заголовка.

Элементы управления

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

Пример расположения элементов управления

Этого можно добиться с помощью того же свойства justify-content: space-between, если вам необходимо, чтобы крайние элементы “прилипали” к краям блока. Если требуется разместить элементы так, чтобы между ними и краями родителя оставалось примерно одинаково места, то воспользуйтесь свойством flex: 1. Вместо 1 подставьте нужное вам число, пока не получите оптимальное расстояние между компонентами.

Элементы форм

Речь здесь преимущественно про простые формы, например, оставления комментарий. Обычно она представляет из себя поле ввода, кнопку отправки и несколько вспомогательных кнопок, например, добавления файлов и эмодзи. При этом нужно сделать так, чтобы поле могло растягиваться, адаптируясь под размеры экрана.

Форма отправки комментария

Реализовать подобную задумку позволяет свойство flex: 1 auto. Цифры можно вписать свои для более корректной настройки отступов. Значение auto прописывать обязательно. В противном случае расстояние между элементами формы не сможет корректно адаптироваться к изменениям размеров экрана.

Блоки с комментариями

Большинство комментариев это поле с текстом и аватаркой пользователя. Иногда там может быть блок с управляющими элементами, например, кнопками лайка, ответа и так далее. Все это удобно разнести в одной плоскости по горизонтали, а с этой задачей отлично справляются флексбоксы. В представленном примере ниже текст комментария занимает практически все свободное пространство, оставляя лишь одну ячейку под блок с аватаркой пользователя. Подобное реализовано с помощью свойства flex: 1 1 auto.

Блок с комментарием

Блоки карточек

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

Вот пример использования этого свойства из практики:

Здесь при нормальном размере экрана элементы карточки выстраиваются в колонку. Когда размер экрана уменьшается до 800 пикселей и менее, то компоненты перестраиваются в ряд. Всего одним свойством получилось быстро и без “костылей” адаптировать поведение макета.

Пример разного поведения карточек при изменении размеров экрана

Меню со вкладками

В этом случае элементы должны занимать все пространство родителя, без каких-либо отступов. Добиться этого с помощью Flexbox совсем несложно – достаточно прописать свойство flex-grow. В значение к нему поставьте 1. С такими настройками отступов между элементами не остается и они равномерно занимают пространство родителя.

Меню с разными вкладками

Списки с карточками

Механизм формирования элементов во Flexbox позволяет настроить направление следования с помощью всего одного свойства. По умолчанию все элементы располагаются вертикали слева направо. Однако row-reverse позволяет изменить расположение справа налево. Это очень удобно для оформления карточек подобного типа.

Пример реверсии на одной из карточек во flexbox

Заключение

CSS Grid и Flexbox вполне можно использовать при верстке одного шаблона. Главное, понимать, где какую технологию лучше использовать. Там, где элементы можно выровнять в одной плоскости отлично подходит Flexbox, а там, где их требуется располагать по определенной сетке, лучшей подойдет CSS Grid. С опытом разработчик учится быстро определять, как быстрее и лучше сделать задуманное. Рассмотренные примеры помогут быстрее определиться с выбором технологии.