Направление flex-direction¶
Flex-элементы во flex-контейнере могут иметь определенное направление, а именно они могут располагаться в виде строк или в виде столбцов.
Для управления направлением элементов CSS3 предоставляет свойство flex-direction . Оно определяет направление элементов и может принимать следующие значения:
- row : значение по умолчанию, при котором элементы располагаются в виде строки слева направо
- row-reverse : элементы также располагаются в виде стоки только в обратном порядке справа налево
- column : элементы располагаются в столбик сверху вниз
- column-reverse : элементы располагаются в столбик в обратном порядке снизу вверх
Например, расположение в виде строки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
html> head> meta charset="utf-8" /> title>Flexbox в CSS3title> style> .flex-container display: flex; border: 1px solid #ccc; > .row flex-direction: row; > .row-reverse flex-direction: row-reverse; > .flex-item text-align: center; font-size: 1.1em; padding: 1.5em; color: white; > .color1 background-color: #675ba7; > .color2 background-color: #9bc850; > .color3 background-color: #a62e5c; > style> head> body> h3>Rowh3> div class="flex-container row"> div class="flex-item color1">Flex Item 1div> div class="flex-item color2">Flex Item 2div> div class="flex-item color3">Flex Item 3div> div> h3>Row-reverseh3> div class="flex-container row-reverse"> div class="flex-item color1">Flex Item 1div> div class="flex-item color2">Flex Item 2div> div class="flex-item color3">Flex Item 3div> div> body> html>
Аналогично работает расположение в виде столбца:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
html> head> meta charset="utf-8" /> title>Flexbox в CSS3title> style> .flex-container display: flex; border: 1px solid #ccc; > .column flex-direction: column; > .column-reverse flex-direction: column-reverse; > .flex-item text-align: center; font-size: 1em; padding: 1.2em; color: white; > .color1 background-color: #675ba7; > .color2 background-color: #9bc850; > .color3 background-color: #a62e5c; > style> head> body> h3>Columnh3> div class="flex-container column"> div class="flex-item color1">Flex Item 1div> div class="flex-item color2">Flex Item 2div> div class="flex-item color3">Flex Item 3div> div> h3>Column-reverseh3> div class="flex-container column-reverse"> div class="flex-item color1">Flex Item 1div> div class="flex-item color2">Flex Item 2div> div class="flex-item color3">Flex Item 3div> div> body> html>
CSS Flexbox: легкий старт для новичков

CSS Flexible Box Layout Module (CSS модуль для макетов с гибкими блоками), проще говоря Flexbox («флексбокс») — это технология, упрощающая верстку отдельных элементов HTML-страницы. Этот модуль предоставляет возможность при помощи CSS3 быстро и удобно позиционировать блоки на странице, подстраиваясь под разные варианты разрешения экрана. В этой статье мы узнаем, как быстро и легко верстать современные веб-страницы на основе этой техники.
Курс Управління командою в бізнесі.
Онлайн-курс для ефективного управління командою, спрямований на створення проактивних та самостійних команд, де мікроменеджмент не потрібний.

1. Флексбокс — принцип работы

С появлением Flexbox позиционирование элементов существенно упростилось. До появления Flexbox для позиционирования блоков приходилось использовать свойства float : left/right и тому подобные вещи, нужно было также указывать ширину и отступ, например, padding — отступ от содержимого до края блока, margin — расстояние от одного блока до другого и т.д.
Курс Финансовый директор.
Отримайте комплексне розуміння фінансової діяльності. Час підніматись по карʼєрним сходам.

Кроме того, нужно было еще все это и высчитывать например, для определенного значения margin от общей ширины блока необходимо отнять, скажем, один или два процента . Это, конечно было не сложно, но занимало время. С появлением флексбокса все упростилось — он более функционален и просто решает данные задачи. Позиционирование дочерних объектов стало намного легче.
Так что же такое Flexbox? Это модуль, включающий в себя ряд свойств и их значений, как для родителя флекс-контейнера, так и для дочерних флекс-элементов (флексов). Забегая вперед, сразу перечислим основные CSS-свойства для описания Flex-технологии.
В случае флекс-контейнера мы имеем дело со следующими свойствами: display , flex-direction , flex-wrap , flex-flow , direction wrap , justify-content , align-content , align-items , column-gap и gap .
Для элементов контейнера задействуются такие CSS-свойства: flex-grow , flex-shrink , flex-basis , flex: , align-self и order . Значения всех этих свойств и их влияние на верстку мы будем рассматривать ниже.
Овладеть тонкостями работы с CSS Flexbox можно на курсах наших партнеров в Mate Academy, Robot Dreams, Powercode Академия. Практикующие специалисты помогут вам освоить нужную информацию на 100%.
Сильная сторона Flexbox заключается в его адаптивности под направление текста. Гибкие блоки сжимаются и растягиваются, выстраиваются в ряд или образуют столбцы, выравниваются как по вертикали, так и по горизонтали, причем их очередностью можно управлять через CSS. При этом, их размер может быть заранее неизвестен или постепенно меняться — отсюда и название flex , означающее «гибкий». Корректируя ориентацию и размер элементов, контейнер Flexbox каждый раз подстраивается под требуемые условия.

2. Краткая история редакций
Разработка CSS Flexible Box Layout началась еще в 2008 году. С тех пор вышло несколько редакций, имеющих свои особенности:
-
2008 — CSS Working Group выдвигает новую модель верстки Flexible Box, разработанную на основе языков разметки XUL (XML User Interface Language — Mozilla) и XAML (Extensible Application Markup Language — Microsoft).
Курс Python.
Цю мову програмування використовують від базових концепцій до складних застосувань у сферах штучного інтелекту. Після проходження курсу гарантовано отримай роботу в ІТ.
Ознакомиться подробнее с поддержкой и совместимостью с разными типами браузеров можно на сайте caniuse.com.
3. Введение в основы: главная и поперечная ось flex-контейнера, flex-direction

Для конфигурации модуля Flexbox применяется набор терминов. Прежде всего это две оси, на которые нужно ориентироваться при позиционировании — главная и поперечная в документации Mozilla она называется побочной .

Главной осью flex -контейнера ( main axis ) является направление, относительно которого располагаются дочерние элементы контейнера. Поперечная ось представляет собой направление, перпендикулярное главной оси.
Перевести контейнер в «гибкое» состояние несложно. Необходимо всего лишь изменить свойство display:flex или display:inline-flex .
HTML
CSS .my-flex-container
Flex-элементы следует воспринимать как первичные раскладки в горизонтальных рядах или вертикальных столбцах. Направление главной оси устанавливается базовым css -свойством flex-direction . Оно содержит четыре возможных значения:
Курс Проджект-менеджмент в IT.
Навчайся у найкращих, курс проводить Тарас Федорук, найкращий PM за версією Ukrainian IT Awards у 2019 році.
- row
- row-reverse
- column
- column-reverse
Так, например, при выборе row или row-reverse главная ось проходит вдоль строки в направлении ряда. При выборе column или column-reverse , главная ось имеет направление сверху вниз — в направлении блока.
.parent < flex-direction: row /* default */ или row-reverse или column или column-reverse >

Важное обстоятельство, которое стоит учитывать: при изменении осей меняются только направления движения блоков внутри, а начало, конец и размер контейнера остаются прежними. Также следует иметь в виду, что Flexbox не определяет режим написания документа.
Ранее CSS был оптимизирован под горизонтальный режим, с режимом письма слева направо. Теперь же логичное предположение о том, что строка текста идет из верхнего левого угла макета в правую сторону, а новые строки появляются одна под другой, уже неверно.
4. Правила переноса блоков: flex-wrap и flex-flow
В процессе верстки flex -элементы будут пытаться расположиться на одной строке. Такой порядок размещения флексов можно изменить, позволив элементам перескочить на следующую строку, по мере необходимости. Для этого необходимо настроить свойство flex-wrap :
.container

- nowrap (вариант по умолчанию) — элементы контейнера занимают положение в один ряд (если direction=row ) или в одну колонку (если direction=column ). Такое размещение не зависит от того, помещаются они в контейнер или нет.
- wrap — если элементы не помещаются в контейнер, тогда они переносятся на следующий ряд. Тем самым осуществляется движение элементов вдоль поперечной оси.
- wrap-reverse — перемещение аналогичное wrap, только не вниз, а вверх (в обратном направлении).
Поскольку свойства flex-direction и flex-wrap часто используются вместе, то для удобства было придумано свойство flex-flow . Оно может одновременно иметь значения и flex-direction , и flex-wrap — разделенные пробелом, — а может содержать значение только для какого-то одного свойства.
/* исключительно для flex-direction */ flex-flow: row; flex-flow: row-reverse; flex-flow: column; flex-flow: column-reverse; /* исключительно для flex-wrap */ flex-flow: nowrap; flex-flow: wrap; flex-flow: wrap-reverse; /* сразу оба значения: и flex-wrap, и flex-direction */ flex-flow: row nowrap; flex-flow: column wrap; flex-flow: column-reverse wrap-reverse;
5. Выравнивание флексов
Относительно основной оси для выравнивания используется justify-content .
Положением флексов относительно основной оси управляет CSS-свойство justify-content .

Чтобы использовать различные способы размещения элементов, задаются следующие значения justify-content (при direction=row выравнивание выполняется по горизонтали, при direction=column — по вертикали):
- flex-start (дефолтный вариант) — положение компонентов контейнера выравниваются относительно начала главной оси.
- flex-end — блоки контейнера сдвигаются в конец главной оси.
- center — центр группы элементов контейнера совмещается с центром главной оси.
- space-between — первый компонент контейнера помещается в начало главной оси, последний элемент – ставится в конец. Прочие элементы равномерно заполняют свободное место.
- space-around — все части контейнера равномерно выставлены вдоль главной оси, заполняя все свободное пространство поровну.
- space-evenly — части распределяются так, чтобы расстояние между любыми соседними компонентами (и расстояние до краев) было одинаковым.
Относительно поперечной оси: свойство align-items и align-content .
Свойство align-items говорит о том, как флексы будут располагаться относительно поперечной оси. Существуют несколько вариантов выравнивания:
- flex-start/ start/ self-start — компоненты позиционируются либо по верхнему краю (при расположении в строку), либо по левому краю (при расположении в столбик) контейнера.
- flex-end/ end/ self-end — вариант размещения элементов по нижнему краю контейнера (при расположении в строку) или по правому краю (при расположении в столбик).
- stretch — такое значение свойство принимает по умолчанию. В этом случае flex -элементы растягиваются на всю высоту контейнера (при расположении в строку) либо на всю ширину контейнера (при расположении в столбик).
- center — центрирование элементов относительно поперечной оси flex-контейнера.
- baseline — элементы выравниваются в соответствии со своей базовой линией.
- safe и unsafe — эти слова могут комбинироваться с любыми из перечисленных выше значений, предотвращая недоступность содержимого элементов в процессе выравнивания.
.container

Align-content
Этот инструмент применяется не очень часто. В разметке он обеспечивает выравнивание рядов с элементами по поперечной оси. То же, что justify-content , только для противоположной оси. Align-content работает только в многострочном режиме (при flex-wrap:wrap или flex-wrap:wrap-reverse ).
- stretch (свойство по умолчанию) — строки с элементами растянуты, чтобы заполнить все имеющееся пространство.
- flex-start — ряды элементов прижаты к началу flex -контейнера.
- flex-end — ряды элементов прижаты к концу flex -контейнера.
- center — положение рядов блоков устанавливается по центру flex -контейнера.
- space-around — ряды блоков равномерно распределены от начала до конца flex-контейнера, разделяя все свободное пространство поровну.
- space-between — первый ряд блоков располагается в начале flex -контейнера, последний ряд блоков блок — в конце, все остальные ряды равномерно распределены в оставшемся пространстве.

Как уже было сказано выше, свойство align-content должно использоваться с контейнером, а не его дочерними элементами. Отдельным флексам можно переопределять правило выравнивания при помощи свойства align-self .

6. Очередность компонентов флексбокс: order
Компоненты флекс-контейнера размещены в некоторой последовательности. Задав значение order , очередностью их расположения можно управлять. Исходное значение свойства order: 0 . Для задания очередности появления компонентов в контейнере укажите числовое значение
.child < order: 0 /* дефолтное значение*/ или >

Порядок компонентов зависит от очередности их появления в HTML-коде, а также от направления ряда. Когда компонент не является флекс-элементом иными словами, он не включен в родительский элемент — блочный или строчный флекс-контейнер , то любые свойства, предназначенные для работы с флекс-элементами, не окажут на такие части контейнера никакого эффекта. То же самое относится и к свойству order . Компоненты контейнера с идентичными значениями order возвращаются к исходному способу группировки.
Ниже показан вариант, когда order задействуется для выставления элементов 1, 2, 3, 4, 5 в очередность 3, 5, 1, 2, 4.

Здесь следует понимать, что числовые значения, присваиваемые элементам, не являются их идентификаторами и порядковыми номерами. Это всего лишь «веса» занимаемой позиции. Например, вместо чисел 0, 1, 2 и т.д. вы с тем же успехом можете использовать 100, 200, 300 и даже отрицательные числа.
7. Настройка «гибкости» элементов (flex-grow, flex-shrink)
«Гибкостью растяжения» отдельных элементов можно управлять. Для этого используется пропорция, числовые значения которой определяют, насколько будет растянут тот или иной флекс внутри контейнера.
Например, если все компоненты имеют значение этого свойства равным единице, а один блок имеет свойство, равное двум, то его размер будет в два раза больше. По умолчанию значение flex-grow равно нулю.
.item < flex-grow: ; > flex-shrink
Если flex-grow отвечает за растяжение элементов, то flex-shrink управляет их сжатием. Значение по умолчанию — единица. Чем больше число, тем меньше «жадность» блока — меньше его размер:
.item < flex-shrink: ; >

flex-basis:
Это свойство задает базовую ширину флекс-компонента — ширину — до того, как будут рассчитаны прочие условия, влияющие на размер. Значение указывается в px , em , rem , %, vw , vh и т.д. Конечная ширина будет определяться базовым значением ширины, а также величинами flex-grow и flex-shrink и, конечно, содержанием блока. По умолчанию используется режим auto, в котором элемент имеет базовую ширину относительно контента внутри него.

Сразу три свойства записываются в короткой форме — flex: . По умолчанию flex: 0 1 auto . Такой вариант записи предпочтительнее, так как более он компактен. Синтаксис записи свойства выглядит так:
.item < flex: none | [ ? || ] >
Последние два свойства флекс-контейнера — column-gap и gap . Они задают размер промежутка между элементами: column-gap — раздвигает колонки, gap — раздвигает и колонки и ряды.

8. CSS Grid Layout vs CSS Flexbox Layout
При работе над очередным макетом у многих пользователей возникает вопрос: какой технологии отдать предпочтение — CSS Grid Layout или CSS Flexbox Layout. Действительно, эти технологии близки и во многих случаях взаимозаменяемы.
Однако между ними есть существенное отличие. Технология CSS Grid Layout управляет положением элементов сразу в двух направлениях — столбцах и строках. Верстка по технологии CSS Flexbox Layout просто этого делать не позволяет. Поэтому если в процессе работы над макетом вы часто задействуете функцию calc() , то, скорее всего, текущая задача оптимально решается не флексбоксом, а именно CSS Grid Layout.

В конечном итоге все сводится к постановке задачи, где прописано поведение элементов в макете. С другой стороны, технология Grid может быть недоступна по причине несовместимости с некоторыми версиями браузеров (например — в IE 11 и ниже). В любом случае технологии CSS Grid Layout и CSS Flexbox Layout не являются альтернативными, а скорее, дополняют возможности друг друга, предлагая в разных случаях более простой код описания макета под какой-то отдельный тип контента .
Заключение
Мы рассмотрели основные задачи и методы управления «гибкой» версткой. Надеемся, наша «шпаргалка» будет вам полезна. Закрепить навыки работы с Flexbox можно только практикой. Поэтому в завершение предлагаем вам также посмотреть видео с мастер-классом по адаптивной верстке.
Также прикладываем ролик, в котором объясняется, в чем отличие Float, Flexbox и Grid CSS
Начинающие знатоки CSS могут попробовать закрепить навыки в игровой форме с помощью забавной игрушки, развивающей понимание тех или иных свойств флексбокса: http://flexboxfroggy.com/. Также будет полезен визуальный конструктор flex -кода, доступный здесь: https://bennettfeely.com/flexplorer/
Курс QA Manual.
Успішна кар’єра в IT-сфері без необхідності глибоких знань програмування. Очікуйте заробітню плату в розмірі 600$ після завершення навчання.
Flexbox
Flexbox — это новый способ располагать блоки на странице. Это технология, созданная именно для раскладки элементов, в отличие от float-ов. С помощью Flexbox можно легко выравнивать элементы по горизонтали и по вертикали, менять направление и порядок отображение элементов, растягивать блоки на всю высоту родителя или прибивать их к нижнему краю.
UPD от 02.02.2017: сделала удобную шпаргалку по флексбоксам, с живыми демками и описаниями из спеки: Flexbox cheatsheet.
В примерах используется только новый синтаксис. На момент написания статьи правильней всего они отображаются в Chrome. В Firefox работают частично, в Safari — вообще не работают.
Спецификация на английском есть тут: w3.org/TR/css3-flexbox.
Согласно сайту caniuse.com, Flexbox не поддерживается 8 и 9-м IE и Opera Mini, а в других браузерах поддерживаются не все свойства и/или требуются префиксы.
Это означает, что технологию нельзя широко использовать прямо сейчас, но уже самое время познакомиться с ней поближе.
Для начала надо знать, что flex-элементы располагаются по осям. По умолчанию элементы располагаются по горизонтали — вдоль main axis — главной оси.
Так же следует иметь в виду, что при использовании Flexbox для внутренних блоков не работают float , clear и vertical-align , а так же свойства, задающие колонки в тексте.
Приготовим полигон для экспериментов:
Один родительский блок (желтый) и 5 дочерних.
Display: flex
И теперь родительскому элементу добавляем display: flex; . Внутренние div-ы выстраиваются в ряд (вдоль главной оси) колонками одинаковой высоты, независимо от содержимого.
display: flex; делает все дочерние элементы резиновыми — flex , а не инлайновыми или блочными, как было изначально.
Если родительский блок содержит картинки или текст без оберток, они становятся анонимными flex-элементами.
Свойство display для Flexbox может принимать два значения:
flex — ведёт себя как блочный элемент. При рассчете ширины блоков приоритет у раскладки (при недостаточной ширине блоков контент может вылезать за границы).
inline-flex — ведёт себя как инлайн-блочный. Приоритет у содержимого (контент растопыривает блоки до необходимой ширины, чтобы строчки, по возможности, поместились).
Flex-direction
Направление раскладки блоков управляется свойством flex-direction .
row — строка (значение по умолчанию);
row-reverse — строка с элементами в обратном порядке;
column-reverse — колонка с элементами в обратном порядке.
row и row-reverse :
column и column-reverse :
Flex-wrap
В одной строке может быть много блоков. Переносятся они или нет определяет свойство flex-wrap .
nowrap — блоки не переносятся (значение по умолчанию);
wrap — блоки переносятся;
wrap-reverse — блоки переносятся и располагаются в обратном порядке.
Для короткой записи свойств flex-direction и flex-wrap существует свойство: flex-flow .
Возможные значения: можно задавать оба свойства или только какое-то одно. Например:
flex-flow: column-reverse wrap;
Демо для row-reverse wrap-reverse :
Order
Для управления порядком блоков служит свойство order .
Возможные значения: числа. Чтобы поставить блок самым первым, задайте ему order: -1 :
Justify-content
Для выравнивания элементов есть несколько свойств: justify-content , align-items и align-self .
justify-content и align-items применяются к родительскому контейнеру, align-self — к дочерним.
justify-content отвечает за выравнивание по главной оси.
Возможные значения justify-content :
flex-start — элементы выравниваются от начала главной оси (значение по умолчанию);
flex-end — элементы выравниваются от конца главной оси;
center — элементы выравниваются по центру главной оси;
space-between — элементы выравниваются по главной оси, распределяя свободное место между собой;
space-around — элементы выравниваются по главной оси, распределяя свободное место вокруг себя.
flex-start и flex-end :
Align-items
align-items отвечает за выравнивание по перпендикулярной оси.
Возможные значения align-items :
flex-start — элементы выравниваются от начала перпендикулярной оси;
flex-end — элементы выравниваются от конца перпендикулярной оси;
center — элементы выравниваются по центру;
baseline — элементы выравниваются по базовой линии;
stretch — элементы растягиваются, занимая все пространство по перпендикулярной оси (значение по умолчанию).
Align-self
align-self также отвечает за выравнивание по перпендикулярной оси, но задается отдельным flex-элементам.
Возможные значения align-self :
auto — значение по умолчанию. Означает, что элемент использует align-items родительского элемента;
flex-start — элемент выравнивается от начала перпендикулярной оси;
flex-end — элемент выравнивается от конца перпендикулярной оси;
center — элемент выравнивается по центру;
baseline — элемент выравнивается по базовой линии;
stretch — элемент растягивается, занимая все пространство по высоте.
Align-content
Для управления выравниванием внутри многострочного flex-контейнера есть свойство align-content .
flex-start — элементы выравниваются от начала главной оси;
flex-end — элементы выравниваются от конца главной оси;
center — элементы выравниваются по центру главной оси;
space-between — элементы выравниваются по главной оси, распределяя свободное место между собой;
space-around — элементы выравниваются по главной оси, распределяя свободное место вокруг себя;
stretch — элементы растягиваются, заполняя всю высоту (значение по умолчанию).
Ps: Некоторые штуки мне так и не удалось увидеть в действии, например, строчку flex-flow: column wrap или полную запись того же flex-direction: column; flex-wrap: wrap; .
Элементы стоят столбиком, но не переносятся:
Не срабатывает wrap при flex-direction: column; , хотя в спеке это выглядит вот так:
Думаю, со временем заработает.
UPD от 21.06.2014: всё работает, если задать блоку высоту. За подсказку спасибо SelenIT2.
Показать комментарии
Сайдбар
Статьи
- Математические функции в CSS
- Адаптивное видео с помощью встроенных математических функций CSS
- Недоступность в картинках
- Единицы размеров в CSS
- Генератор цветовых тем
- Jekyll → Gatsby
- Вариативные шрифты
- Размеры в SVG
- Адаптивный Pixel Perfect
- Логотип не отвечает или временно недоступен
- SVG-паттерны
- Мыльные пузыри на SVG
- SVG-градиенты
- Весёлая консолька
- SVG-маски
- Умная прокрутка со Scroll Snap Points
- CSS-анимации для ротации изображений
- Анимированные SVG-маски
- Странности обводки в SVG
- SVG-прелоадеры
- Анимируем градиенты ещё раз
- Background-blend-mode
- Возможности оформления SVG
- CSS и SVG маски
- Nth-child и nth-of-type
- SVG-иконки
- SVG: заливка и обводка
- SVG-path
- SVG: группировка и переиспользование элементов
- SVG-фигуры и трансформации
- SVG
- СSS-градиенты и 3D
- Рисовалка анимированных теней
- Свежие CSS-паттерны
- CSS-паттерны
- Радиальные градиенты
- Линейные градиенты
- Крестики-нолики на CSS
- Border-image
- Электронные часы на CSS и JS.
- Сколько весят селекторы?
- Символы юникода
- Свойство content
- Анимируем CSS-градиенты
- Текстовые эффекты
- Древовидный список на CSS
- Css-селекторы, часть 2
- Css-селекторы
- Контекст наложения
- Два способа «прошить» элемент по краю
- Box-sizing
- Цвета в CSS
- Фон под строчками: добавляем поля
- Box-shadow
- Css-фигуры: лепесток
- Transform
- Css Animation
- 3D-куб
- Border-radius
- First letter
- Эти глаза напротив
- CSS-фигуры
- Стрелки с помощью свойства border
- Flexbox
Страницы
- SVG: полезные ссылки
- CSS-селекторы одной таблицей
- Таблица именованных цветов
- Функции Transform
- Свойства Transform
- Свойства Animation одной таблицей
- Разный синтаксис Flexbox
- Свойства Flexbox одной таблицей
Проекты
CSS Grid. Практические примеры

Будущее наступило: CSS Grid поддерживается всеми современными браузерами, девтулзы для работы с ним доступны и в Firefox, и в Хроме, а с автопрефиксером и осторожностью можно использовать гриды даже в IE 10/11.
Но, знакомясь с туториалами, я заметил, что большинство из них фокусируются либо на том, как работают конкретные свойства, либо на том, как сверстать постер или журнальный разворот. Да, это интересно, помогает погрузиться в тему и показывает всю мощь нового инструмента, но как использовать полученные знания в работе?
В этой статье я хочу поделиться накопленным за последний год опытом использования CSS Grid в коммерческих проектах. Ниже я разберу примеры, как применять гриды для вёрстки всей страницы, групп элементов и отдельных компонентов.
Для демонстрации я буду пользоваться девтулзами Хрома:

Если вы пока мало знакомы с гридами, статья всё равно может оказаться полезной, но за подробным описанием свойств и их возможных значений советую обращаться к гайду от CSS-Tricks.
Колоночная сетка
Начнём с того, как использовать гриды для вёрстки всей страницы. Если вы привыкли верстать стандартной колоночной сеткой (например, из бутстрапа), то гриды с лёгкостью позволяют придерживаться такого подхода.
Для этого достаточно создать грид-контейнер с 12 равными по ширине колонками, а дальше у детей указывать, какие колонки им занять:
.main < display: grid; grid-template-columns: repeat(12, 1fr); grid-gap: 1rem; >.hero < grid-column: 1 / span 12; >.title < grid-column: 3 / span 4; >
Чтобы адаптировать такую вёрстку под маленькие разрешения, можно заменить сетку на 6-колоночную и обновить позиции элементов:
@media (max-width: 720px) < .main < grid-template-columns: repeat(6, 1fr); >.hero < grid-column: 1 / span 6; >.title < grid-column: 2 / span 3; >>
Пример использования такого подхода можно увидеть на нашем лендинге:

12-колоночная сетка на десктопном разрешении

6-колоночная сетка на мобильном разрешении
С CSS Grid можно не ограничиваться колонками и задать количество строк ( grid-template-rows ) тоже, чтобы иметь возможность точно позиционировать каждый элемент ( grid-row ).
Разметка страницы на области
Возможности CSS Grid не заканчиваются на колоночной сетке и включают новый способ размечать страницу. С помощью grid-template-areas можно разделить страницу на области, а части страницы раскидать по этим областям:
body < display: grid; grid-template-areas: 'header header' 'menu content' 'footer footer'; grid-template-columns: 12rem 1fr; grid-template-rows: 5rem 1fr 3rem; >header < grid-area: header; >article < grid-area: content; >aside < grid-area: menu; >footer

На флексах для такого простого лейаута пришлось бы делать несколько вложенных обёрток, а информация о размерах блоков размазалась бы по обёрткам и их детям. C CSS Grid всё это лежит в одном месте — в контейнере. При этом описание областей в CSS даёт представление о том, как результат будет выглядеть в браузере.
Более того, в такую разметку легко добавить адаптив, ничего не меняя в детях:
@media (max-width: 600px) < body < grid-template-areas: 'header' 'menu' 'content' 'footer'; grid-template-columns: 1fr; grid-template-rows: 5rem auto 1fr 3rem; >>

Вот полный код примера:
Витрина карточек
От лейаута страницы переходим к её содержимому.
Витрина — пожалуй, самый часто встречаемый контейнер для однородных элементов. С помощью неё могут отображаться товары интернет-магазина, новости, фотографии в альбоме, в общем, что угодно прямоугольной формы.
Верстая такую витрину на флексах, я каждый раз сталкивался с одними и теми же проблемами:
- Как задать отступы между карточками? Есть свойство gap, но оно пока ещё плохо поддерживается. Поэтому приходится давать всем элементам отступы друг от друга, а у их контейнера отрицательным отступом компенсируем лишние отступы крайних элементов.
- Как сделать так, чтобы карточки в последнем ряду не растягивались на полную ширину? Флекс будет тянуть элемент на всё доступное место, так что придётся либо хардкодить ширину элементов, либо заполнять последнюю строку невидимыми элементами.
- Как сделать адаптив? Нужно опытным путём вычислить ширину, на которой наши карточки перестают нормально вмещаться, и на ней поправить значения ширины для карточек, чтобы было меньше столбцов.
Гриды решают все эти проблемы буквально в 3 строки:
main
- Отступы между элементами явно указаны в grid-gap .
- Карточки в последнем ряду будут занимать свои колонки и не будут растягиваться.
- Адаптив без медиа-запросов: у карточки указана минимально допустимая ширина 250px, а дальше сетка уже сама считает, сколько таких карточек поместится в строку.
Вот полный код примера:
Другие варианты витрин на гридах:
- CodePen витрины с горизонтальным скроллом при сужении экрана;
- CodePen витрины с карточками разных размеров;
- CodePen с masonry grid;
- статья в CSS-Tricks, где подробно разбирается пример адаптивной сетки с карточками разных размеров.
Форма
Типичная форма состоит из 2 столбцов: в левом идут названия полей, в правом — инпуты. Проблема с таким расположением иногда заключается в том, что мы не знаем, какой длины будут названия полей, но хотим, чтобы все строки формы были выровнены.
Сделать такое на флексах можно, только захардкодив ширину левой колонки, чтобы в каждой строке она была одинаковой. Можно сделать на table, но это будет использованием не по назначению. И тут на помощь приходит CSS Grid:
form

Левой колонке мы задаём ширину auto , чтобы она подстраивалась под длину лейблов, а правой колонке выделяем 1fr , то есть всё оставшееся от левой колонки место.
Чтобы сделать форму вертикальной на мобильных, мы можем заменить сетку на 1-колоночную и уменьшить отступ между лейблом и инпутом, образовавшийся из-за grid-gap :
@media (max-width: 500px) < form < grid-template-columns: 1fr; >label < margin-bottom: -0.75rem; >>

И на десктопном, и на мобильном разрешениях кнопка сабмита занимает полную ширину контейнера. Это происходит благодаря следующей строчке:
button < grid-column: 1 / -1; >
Эта запись означает, что кнопка будет расположена между самой первой вертикальной линией сетки (1) и самой последней (-1). То есть она будет занимать целую строку, независимо от того, сколько в сетке столбцов.
Вот полный код примера:
Группировка ячеек
В форме может понадобиться объединить инпуты в , но с гридами не так очевидно, как это сделать. Грид (как и флекс) описывает только расположение своих детей. Если в детей вложены другие элементы, то на них грид уже не влияет. В будущем мы сможем решать такие задачи с помощью subgrid, но как быть сейчас?
Я пользуюсь для таких целей display: contents , но стоит учитывать, что у него:
- слабее поддержка, чем у гридов (в основном из-за IE);
- есть проблемы с доступностью.
Элемент с display: contents при рендеринге заменяется своими детьми, поэтому если такой элемент лежит внутри грид-контейнера, то его дети будут располагаться на сетке так, будто они сами лежат внутри грид-контейнера.
Так как сам элемент с display: contents не рендерится, то и визуальных свойств у него быть не может. Но зато он может реагировать на события мыши и определять css-переменные. Вот пример, как с помощью такого элемента реализовать ховер на группу ячеек грида:
Карточка с вариациями отображения
Теперь переходим к конечным компонентам, при вёрстке которых нас тоже может выручить грид.
Один из таких компонентов — информационная карточка (например, товара или объявления). Часто у таких карточек есть не один вариант отображения, а сразу несколько. Например, нам нужно реализовать адаптив, красиво утрамбовывая элементы карточки в меньший объём. Или предоставить несколько вариантов отображения для разных мест размещения: на витрине, в рекламе или в попапе предпросмотра.
Гриды позволяют красиво решать такие задачи, даже не меняя HTML-разметку. Для примера разберём вот такую карточку объявления о сдаче в аренду квартиры:

Карточка размера L
.card.size_l

Карточка размера M
.card.size_m

Карточка размера S
.card.size_s
Все 3 состояния используют одну HTML-разметку, но в CSS у них разная конфигурация областей и положения элементов. Обратите внимание, что на размерах M и S некоторые блоки располагаются друг поверх друга. Это тоже сделано на гридах, но уже с помощью наложения.
Наложение элементов в одной области
Приём в том, что мы разных детей складываем в одну и ту же grid-area . При этом они не располагаются, как обычные блоки, друг под другом, а накладываются поверх. Дальше с помощью align-self / justify-self можно поставить каждого ребёнка в свой угол:

.photo < grid-area: photo; >.size_s .price < grid-area: photo; align-self: start; justify-self: stretch; >.size_s .date < grid-area: photo; align-self: end; justify-self: start; >.size_s .actions
Частичное наложение элементов
Если располагать элементы не по областям, а назначать им положение в сетке с помощью grid-row / grid-column , то наложение элементов на сетке можно сделать частичным:
В данном примере кнопка частично накладывается на фото, но избегает наложения на текст справа от неё. С абсолютным позиционированием достигнуть такого эффекта было бы сложнее, так как кнопка была бы вырвана из потока и наезжала на текст.
Столбчатая диаграмма
Ещё один пример из практики — график столбиками (bar chart). Тут использование грида позволяет каждому сегменту графика пропорционально растягивать всю колонку:

- Если в какой-то группе станет больше столбиков, то место под подпись тоже увеличится.
- И наоборот — если где-то будет длинная подпись, то увеличится место под столбики.
В реальной жизни количество сегментов было динамическое, так что значение для свойства grid-template-columns формировалось в JS. Тут для упрощения возьмём график из 3 сегментов с разным количеством столбиков в каждом. Для каждой вертикальной и горизонтальной линии указываем название, чтобы проще было располагать на этих линиях элементы:
.bar-chart < display: grid; grid-template-columns: [left] auto [bar1] auto [bar2] auto [bar3] auto [right] auto; grid-template-rows: [top] auto [center] 10rem [bottom] auto; >.axis < grid-row: center; grid-column: left; >.unit
Теперь можно довольно легко добавить вариации положений основных элементов графика: лейблов, оси, единиц измерения. Благодаря именованным линиям, можно явно описывать, на какую линию мы хотим переместить элемент:
.axisOnRight .axis < grid-column: right; >.unitOnBottom .unit
Попробовать переключение в деле можно, покликав на кнопки под графиком:
Ложки дёгтя
Используя CSS Grid, стоит учитывать и некоторые ограничения:
- Анимации размера столбцов/строк предусмотрены в спеке, но поддерживаются только в Firefox. Впрочем, можно дать столбцу размер auto , а анимировать размер его содержимого.
- Subgrid тоже пока поддерживается только в Firefox. Его появление в остальных браузерах откроет возможности для новых подходов и упростит группировку элементов в HTML. Также с помощью subgrid можно будет вообще всю страницу уложить в одну сетку. Так что ждём.
- С осторожностью используйте гриды в случаях, когда в них вложены флексы и размер контента может динамически меняться. Это может вызвать проблемы с производительностью из-за большого количества пересчётов. Держите руку на пульсе счётчика FPS и вместо Nfr используйте minmax(Xpx, Nfr) , чтобы упростить пересчёт.
Заключение
По итогам года с гридами могу сказать, что использование CSS Grid не только упростило мою работу, но и сделало её интереснее. Гриды не пытаются заменить флексбокс или таблицы, а дают верстальщикам современный и мощный инструмент. Когда удаётся использовать гриды для подходящей задачи, решение обычно получается простым и наглядным.
Надеюсь, на этих примерах мне удалось показать пользу гридов, а кого-то даже вдохновить их попробовать.

Ежемесячная рассылка CSSSR
Новости, свежие статьи и многое другое
