Gap — светлое будущее для отступов в Flexbox (как в Grid)
Одна из моих любимых частей спецификации CSS Grid — это grid-gap . Они позволяют легко создавать отступы между элементами внутри сетки.
Margins и приёмы, к которым мы прибегаем, чтобы реализовать их в разных ситуациях, долгое время были одним из главных моментов, раздражающих меня в CSS.
W3C порекомендовала отказаться от свойства grid-gap в пользу простого gap и его использования в Flexbox и Multi-Column.
В этом руководстве мы посмотрим, как добавляли margins в Flexbox раньше и как это делает свойство gap , позволяя нам получить внутренние отступы без дополнительных ухищрений.
Margins в обычной Flexbox-сетке
В этом примере мы возьмем группу блоков, используем Flexbox для создания стиля сетки, а затем отделим блоки друг от друга с помощью margins.
Начнём с базового HTML. Имеем flex-container и набор flex-item.
Благодаря поведению Flexbox, содержимое расположится друг рядом с другом. Отталкиваясь от значения ширины контейнера, определим размер дочерних элементов и затем позволим им переносится с помощью свойства flex-wrap .
.flex-container < display: flex; flex-wrap: wrap; >.flex-item < width: calc(100% / 3); >

Это даёт нам блоки идеального размера, равные 1/3 ширины контейнера. Давайте зададим margins, чтобы добавить пространство по вертикали и горизонтали между каждым элементом.
.flex-item < width: calc(100% / 3); margin-right: 1rem; margin-bottom: 1rem; >

Ой! Наши элементы, являющиеся 1/3 контейнера, больше не помещаются в ширину родительского элемента. Хотя margins между рядами получились вполне корректными и не вызвали проблем.
Нам понадобится задать ширину дочерних элементов с учетом появившегося дополнительного пространства, образованного margin. Также нужно обнулить свойство margin-right для каждого третьего элемента.
Теперь у нас остались два margins, равных 1rem и мы должны вычесть эти 2rem равномерно из ширины всех трёх элементов.
flex-item < // width: calc(100% / 3); width: calc((100% / 3) - (2rem / 3)); // one-third - two margins divided equally among 3 items margin-right: 1rem; margin-bottom: 1rem; >.flex-item:nth-child(3n)

Выглядит слишком сложно? Для меня да. Существуют более простые способы сделать это, но они также не дают вам точных 1rem промежутков между колонками. Этот сложный код также существенно усложняет адаптивный дизайн.
Когда свойство gap станет доступным для использования в Flexbox во всех браузерах, код станет намного чище. Мы можем также перейти от установки ширины для дочерних элементов, к использованию свойств flex-grow , flex-shrink и flex-basis .
Установка отступов с помощью Gap
Используя свойство gap, мы избавляемся от необходимости проделывать большинство ухищрений с шириной элементов. Это также позволяет нам вернуться к использованию значений flex-grow/flex-shrink.
В следующем примере мы всё ещё используем свойства display: flex и flex-wrap: wrap для нашего контейнера, но теперь также добавляем свойство gap . Это сокращенное свойство, которое объединяет в себе row-gap и column-gap . Ознакомьтесь с документацией MDN, чтобы узнать обо всех методах.
Теперь, вместо установки ширины для каждого flex-элемента, мы устанавливаем значения flex-grow, flex-shrink и flex-basis. Свойство flex-basis будет определять, какое количество колонок браузеры будут устанавливать в контейнере. Мы всё еще будем использовать функцию calc() для этого, но код в конечном счете станет чище
.flex-container < display: flex; flex-wrap: wrap; gap: 1rem; >.flex-item < flex: 1 1 calc((100% / 3) - 2rem); >

Внимательный читатель также заметит, что теперь это позволяет последним элементам увеличиваться в размере, чтобы заполнить пространство ряда, в котором недостаёт элементов. Это то, что для нас не могут сделать CSS Grid и Flexbox, основанный на ширине элементов.
Бонус: Gap также облегчает достижение отзывчивости
В нашем изначальном примере, если мы хотели изменять количество колонок контейнера в определенных контрольных точках, приходилось пересчитывать ширину И изменять nth-child селекторы, чтобы избавиться от margins.
В примере с использованием gap , всё что нам нужно делать, это корректировать свойство flex-basis, и всё готово.
.flex-item < flex: 1 1 100%; // 1 across at mobile >@media (min-width: 640px) < .flex-item < flex-basis: calc((100% / 2) - 1rem); // 2 across at tabletish >> @media (min-width: 1024px) < .flex-item < flex-basis: calc((100% / 3) - 2rem); // 3 across at desktop >>
Не буду врать, я всё еще предпочитаю CSS Grid для такого шаблона проектирования, но надеюсь, вы увидите несколько примеров использования для этой невероятной новой функции.
Заглядывая в будущее
Сейчас свойство gap поддерживается только в браузере Firefox. Итак, если эта статья вас заинтересовала, я смиренно извиняюсь. Вам придется ждать, пока другие браузеры наверстают упущенное. Надеюсь, они заметят боль разработчиков, связанную с margins и рано или поздно дадут нам новые возможности.
Дополнение от переводчика
Вроде всё же есть приём, позволяющий уже сейчас избавиться от необходимости с помощью, например nth-child(3n) убирать правые отступы у Flex-элементов, прилегающих к правому краю контейнера, да еще и корректируя каждый раз, когда меняется количество колонок во Flex-контейнере.
Конечно, он тоже не идеальный и заключается в следующем:
- В HTML-разметке Flex-контейнер обернуть в дополнительный тег-обертку
- Для дочерних элементов, например, вместо margin-right: 10px , задавать margin-left: 10px
- А чтобы компенсировать увеличивающийся левый отступ, необходимо задать для Flex-контейнера свойство с отрицательным значением margin-left: -10px;
Включаем Flexbox
Устанавливает отображение flexbox для дочерних элементов.
display: flex ;
flex-direction
Определяет направление, в котором расположатся дочерние элементы (в вертикальном или горизонтальном). Префикс -reverse меняет порядок расположения элементов на обратный.
- row(по умолчанию) слева направо
- row-reverse справа налево
- column сверху вниз
- column-reverse снизу вверх
flex-direction: row | row-reverse | column | row | column-reverse ;
justify-content
Устанавливает выравнивание дочерних элементов по горизонтали (если flex-direction: row) или вертикали (если flex-direction: column).
- flex-start(по умолчанию) выравнивание по левому краю
- flex-end по правому краю
- center по середине
- space-between расширяет пространство между элементами так, чтобы первый элемент касался левого края, а последний – правого
- space-around расстояние между элементами одинаково, а расстояние между крайними элементами и границами родителя равно половине расстояния между элементами
- space-evenly расстояния между элементами и границами родителя равны
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly ;
align-items
Устанавливает выравнивание дочерних элементов по вертикали (если flex-direction: row) или по горизонтали (если flex-direction: column).
- stretch(по умолчанию) растянуть элементы так, чтобы заполнить родительский блок
- flex-start выравнивание по верхнему краю
- flex-end по нижнему краю
- center по центру
- baseline по первой строке текста
align-items: stretch | flex-start | flex-end | center | baseline ;
flex-wrap
Разрешает перенос элементов на новую строку. По умолчанию перенос запрещён.
- nowrap(по умолчанию) все элементы выстроены одной строкой
- wrap элементы могут переноситься на следующую строку
- wrap-reverse строки расположены в обратном порядке
flex-wrap: nowrap | wrap | wrap-reverse ;
flex-flow
Сокращённая запись двух свойств flex-direction и flex-wrap. По умолчанию row nowrap
align-content
Если дочерние элементы flexbox не помещаются в ширину блока и разрешён перенос элементов на новую строку (flex-wrap: wrap), то при помощи align-content можно настроить выравнивание этих строк.
Выравнивание может выполняться относительно горизонтали или вертикали в зависимости от значения свойства flex-direction.
- stretch(по умолчанию) растягивает высоту строк настолько, чтобы заполнить блок
- flex-start выравнивание относительно начала блока
- flex-end относительно конца
- center относительно центра
- space-between первая строка в начале блока, последняя в конце. Расстояние между всеми строками равно
- space-around аналогично space-between, но расстояние между первой строкой и началом блока и последней строкой и концом блока равно половине расстояния между строками
Отступы между блоками на flex
Есть следующий макет:
Сверстано так: 
.block3_header < display: flex; align-items: center; justify-content: center; margin-top: 87px; >.block3_header span < font-family: 'Gilroy-Bold'; font-size: 34px; line-height: 42px; text-align: center; color: #070707; >.block3_subText < display: flex; align-items: center; justify-content: center; margin-top: 55px; >.block3_subText span < font-family: 'Gilroy-Medium'; font-size: 18px; line-height: 22px; text-align: center; color: #070707; >.container_skills < margin-top: 80px; >.block3_skills < display: flex; align-content: flex-end; justify-content: space-evenly; align-items: flex-start; >.block3_skill < display: flex; flex-direction: column; align-items: center; >.block3_stars < display: flex; >.block3_stars img < margin-right: 9px; >.block3_stars:last-child < margin-right: 0; >.block3_subTitle < display: flex; margin-top: 24px; margin-bottom: 42px; >.block3_subTitle span
Adobe
Photoshop Adobe
Illustrator Adobe
After Effects Figma
Проблема заключается в то, что по макету карточки с программами находятся ближе друг к другу, чем по факту у меня получились. Есть вариант во флексах как-то уменьшить отступ между блоками?
Гайд по flexbox
Всё, что нужно знать про флексбоксы: основные термины, свойства флекс-контейнера и флекс-элементов, полезные ссылки по теме.
Время чтения: 12 мин
Открыть/закрыть навигацию по статье
- Что это?
- Основные термины
- Свойства флекс-контейнера
- display
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
- gap
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
- Ссылки
- Андрей Захаров советует
- Егор Левченко советует
- Алёна Батицкая советует
- Когда нужно использовать flexbox, а когда grid? Бывают ли исключения?
Контрибьюторы:
- Егор Левченко ,
- Светлана Коробцева ,
- Дмитрий Приходько ,
- Дима Шелков
Обновлено 8 марта 2023
Что это?
Скопировать ссылку «Что это?» Скопировано
Долгое время веб-интерфейсы были статичными — сайты разрабатывались и просматривались только на экранах мониторов стационарных компьютеров. Однако с десяток лет назад, совсем недавно по историческим меркам, у нас появилось огромное разнообразие экранов — от мобильных телефонов до телевизоров, — на которых мы можем взаимодействовать с сайтами. Так родилась необходимость в гибких системах раскладки.
Идея флексбоксов появилась ещё в 2009 году, и этот стандарт до сих пор развивается и прорабатывается. Основная идея флексов — гибкое распределение места между элементами, гибкая расстановка, выравнивание, гибкое управление. Ключевое слово — гибкое, что и отражено в названии (flex — англ. гибко).
Основные термины
Скопировать ссылку «Основные термины» Скопировано
- Флекс-контейнер: элемент, к которому применяется свойство display : flex . Вложенные в него элементы подчиняются правилам раскладки флексов.
- Флекс-элемент: элемент, вложенный во флекс-контейнер.

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

- Начало / конец основной оси: точки в начале и в конце основной оси соответственно. Это пригодится нам для выравнивания флекс-элементов.
- Начало / конец поперечной оси: точки в начале и в конце поперечной оси соответственно.

- Размер по основной оси (основной размер): размер флекс-элемента вдоль основной оси. Это может быть ширина или высота в зависимости от направления основной оси.
- Размер по поперечной оси (поперечный размер): размер флекс-элемента вдоль поперечной оси. Это может быть ширина или высота в зависимости от направления поперечной оси. Этот размер всегда перпендикулярен основному размеру. Если основной размер — это ширина, то поперечный размер — это высота, и наоборот.

Свойства флекс-контейнера
Скопировать ссылку «Свойства флекс-контейнера» Скопировано
display
Скопировать ссылку «display» Скопировано
.container display: flex;> .container display: flex; >
Когда мы задаём какому-то элементу значение flex для свойства display , мы превращаем этот элемент в флекс-контейнер. Внутри него начинает действовать флекс-контекст, его дочерние элементы начинают подчиняться свойствам флексбокса.
Снаружи флекс-контейнер выглядит как блочный элемент — занимает всю ширину родителя, следующие за ним элементы в разметке переносятся на новую строку.
.container display: inline-flex;> .container display: inline-flex; >
Если контейнеру задано значение inline — flex , то снаружи он начинает вести себя как строчный (инлайн) элемент — размеры зависят только от внутреннего контента, встаёт в строку с другими элементами. Внутри это ровно такой же флекс-контейнер, как и при предыдущем значении.
flex — direction
Скопировать ссылку «flex-direction» Скопировано
Свойство управления направлением основной и поперечной осей.
.container display: flex; flex-direction: row;> .container display: flex; flex-direction: row; >
- row (значение по умолчанию) — основная ось идёт горизонтально слева направо, поперечная ось идёт вертикально сверху вниз.
- row — reverse — основная ось идёт горизонтально справа налево, поперечная ось идёт вертикально сверху вниз.
- column — основная ось идёт вертикально сверху вниз, поперечная ось идёт горизонтально слева направо.
- column — reverse — основная ось идёт вертикально снизу вверх, поперечная ось идёт горизонтально слева направо.


flex — flow
Скопировать ссылку «flex-flow» Скопировано
Это свойство-шорткат для одновременного определения значений свойств flex — direction и flex — wrap .
.container display: flex; flex-flow: column wrap;> .container display: flex; flex-flow: column wrap; >
.container display: flex; flex-flow: row nowrap;> .container display: flex; flex-flow: row nowrap; >

flex — grow
Скопировать ссылку «flex-grow» Скопировано
.container display: flex;> .item flex-grow: 1;> .container display: flex; > .item flex-grow: 1; >
Это свойство указывает, может ли вырастать флекс-элемент при наличии свободного места, и насколько. По умолчанию значение равно 0. Значением может быть любое положительное целое число (включая 0).
Если у всех флекс-элементов будет прописано flex — grow : 1 , то свободное пространство в контейнере будет равномерно распределено между всеми.
Если при этом одному из элементов мы зададим flex — grow : 2 , то он постарается занять в два раза больше свободного места, чем его соседи.
flex — shrink
Скопировать ссылку «flex-shrink» Скопировано
.container display: flex;> .item flex-shrink: 3;> .container display: flex; > .item flex-shrink: 3; >
Свойство flex — shrink полностью противоположно свойству flex — grow . Если в контейнере не хватает места для расположения всех элементов без изменения размеров, то свойство flex — shrink указывает, в каких пропорциях элемент будет уменьшаться.
Чем больше значение у этого свойства, тем быстрее элемент будет сжиматься по сравнению с соседями, имеющими меньшее значение.
Значение по умолчанию — 1. Значением может быть любое целое положительное число (включая 0).
Два предыдущих свойства работают с пропорциональным разделением пространства, не с конкретными размерами. Они довольно непростые, даже опытный разработчик не всегда знает, как они в точности работают. Загляните в конец статьи, если хотите подробнее почитать о каждом из них.
flex — basis
Скопировать ссылку «flex-basis» Скопировано
.container display: flex;> .item flex-basis: 250px;> .container display: flex; > .item flex-basis: 250px; >
Свойство flex — basis указывает на размер элемента до того, как свободное место будет распределено (см. flex-grow).
Значением может быть размер в любых относительных или абсолютных единицах: 20rem , 5vw , 250px . А также можно использовать ключевое слово auto (значение по умолчанию). В этом случае при расчёте размера элемента будут приниматься во внимание значения свойств width , max — width , min — width или аналогичные свойства высоты, в зависимости от того, в каком направлении идёт основная ось.
Если никакие размеры не заданы, а свойству flex — basis установлено значение auto , то элемент занимает столько пространства, сколько нужно для отображения контента.
flex
Скопировать ссылку «flex» Скопировано
.container display: flex;> .item flex: 1 1 auto;> .container display: flex; > .item flex: 1 1 auto; >
Свойство-шорткат, с помощью которого можно указать значение трёх свойств одновременно: flex — grow , flex — shrink и flex — basis . Первое значение является обязательным, остальные опциональны.
Значение по умолчанию: 0 1 auto , что расшифровывается как flex — grow : 0 , flex — shrink : 1 , flex — basis : auto .
/* 0 0 auto */flex: none; /* Одно значение, число без единиц: flex-grow */flex: 2; /* Одно значение, ширина/высота: flex-basis */flex: 10em;flex: 30px;flex: auto;flex: content; /* Два значения: flex-grow | flex-basis */flex: 1 30px; /* Два значения: flex-grow | flex-shrink */flex: 2 2; /* Три значения: flex-grow | flex-shrink | flex-basis */flex: 2 2 10%; /* Глобальные значения */flex: inherit;flex: initial;flex: unset; /* 0 0 auto */ flex: none; /* Одно значение, число без единиц: flex-grow */ flex: 2; /* Одно значение, ширина/высота: flex-basis */ flex: 10em; flex: 30px; flex: auto; flex: content; /* Два значения: flex-grow | flex-basis */ flex: 1 30px; /* Два значения: flex-grow | flex-shrink */ flex: 2 2; /* Три значения: flex-grow | flex-shrink | flex-basis */ flex: 2 2 10%; /* Глобальные значения */ flex: inherit; flex: initial; flex: unset;
align — self
Скопировать ссылку «align-self» Скопировано
.container display: flex; align-items: flex-start;> .item align-self: flex-end;> .container display: flex; align-items: flex-start; > .item align-self: flex-end; >
При помощи этого свойства можно выровнять один или несколько элементов иначе, чем задано у родительского элемента. Например, в коде выше у родителя задано выравнивание вложенных элементов по верхнему краю родителя. А для элемента с классом .item мы задаём выравнивание по нижнему краю.
Ссылки
Скопировать ссылку «Ссылки» Скопировано
- Как реально работает flex — grow
- Как реально работает flex — shrink
- Песочница Флексбоксов
- Game: Flexbox Froggy
- Game: Flexbox Defense
- Game: Flexbox Ducky
- Курс по Флексбоксам от Wes Bos
Предыдущая запись
