Что это?
СкопированоДолгое время веб-интерфейсы были статичными — сайты разрабатывались и просматривались только на экранах мониторов стационарных компьютеров. Однако с десяток лет назад, совсем недавно по историческим меркам, у нас появилось огромное разнообразие экранов — от мобильных телефонов до телевизоров, — на которых мы можем взаимодействовать с сайтами. Так родилась необходимость в гибких системах раскладки.
Идея флексбоксов появилась ещё в 2009 году, и этот стандарт до сих пор развивается и прорабатывается. Основная идея флексов — гибкое распределение места между элементами, гибкая расстановка, выравнивание, гибкое управление. Ключевое слово — гибкое, что и отражено в названии (flex — англ. гибко).
Основные термины
Скопировано- Флекс-контейнер: элемент, к которому применяется свойство
display
. Вложенные в него элементы подчиняются правилам раскладки флексов.: flex - Флекс-элемент: элемент, вложенный во флекс-контейнер.
- Основная ось: основная направляющая флекс-контейнера, вдоль которой располагаются флекс-элементы.
- Поперечная (побочная, перпендикулярная) ось: ось, идущая перпендикулярно основной. Позже вы поймёте, для чего она нужна.
- Начало / конец основной оси: точки в начале и в конце основной оси соответственно. Это пригодится нам для выравнивания флекс-элементов.
- Начало / конец поперечной оси: точки в начале и в конце поперечной оси соответственно.
- Размер по основной оси (основной размер): размер флекс-элемента вдоль основной оси. Это может быть ширина или высота в зависимости от направления основной оси.
- Размер по поперечной оси (поперечный размер): размер флекс-элемента вдоль поперечной оси. Это может быть ширина или высота в зависимости от направления поперечной оси. Этот размер всегда перпендикулярен основному размеру. Если основной размер — это ширина, то поперечный размер — это высота, и наоборот.
Свойства флекс-контейнера
Скопированоdisplay
Скопировано.container { display: flex;}
.container { display: flex; }
Когда мы задаём какому-то элементу значение flex
для свойства display
, мы превращаем этот элемент в флекс-контейнер. Внутри него начинает действовать флекс-контекст, его дочерние элементы начинают подчиняться свойствам флексбокса.
Снаружи флекс-контейнер выглядит как блочный элемент — занимает всю ширину родителя, следующие за ним элементы в разметке переносятся на новую строку.
.container { display: inline-flex;}
.container { display: inline-flex; }
Если контейнеру задано значение inline
, то снаружи он начинает вести себя как строчный (инлайн) элемент — размеры зависят только от внутреннего контента, встаёт в строку с другими элементами. Внутри это ровно такой же флекс-контейнер, как и при предыдущем значении.
flex-direction
СкопированоСвойство управления направлением основной и поперечной осей.
.container { display: flex; flex-direction: row;}
.container { display: flex; flex-direction: row; }
Возможные значения:
row
(значение по умолчанию) — основная ось идёт горизонтально слева направо, поперечная ось идёт вертикально сверху вниз.row
— основная ось идёт горизонтально справа налево, поперечная ось идёт вертикально сверху вниз.- reverse column
— основная ось идёт вертикально сверху вниз, поперечная ось идёт горизонтально слева направо.column
— основная ось идёт вертикально снизу вверх, поперечная ось идёт горизонтально слева направо.- reverse
Важный момент: на сайтах с направлением текста справа налево, например, на сайте на арабском языке, для значений row
и row
основная ось будет идти в обратном направлении. Для значений column
и column
своё направление поменяет поперечная ось.
flex-wrap
Скопировано.container { display: flex; flex-wrap: nowrap;}
.container { display: flex; flex-wrap: nowrap; }
По умолчанию значение у свойства flex
— nowrap
. При этом флекс-элементы помещаются (или пытаются уместиться) в один ряд и не переносятся в новый ряд, даже если не влезают в размеры родителя.
Установив значение wrap
, мы можем изменить это поведение, и флекс-элементы будут иметь возможность перенестись в новый ряд, если не влезают в одну линию в рамках родителя.
Ещё одно возможное значение — wrap
. В этом случае элементы будут располагаться снизу вверх, заполнив собой сперва нижний ряд, а те, что не влезли, перепрыгнут в ряд выше.
flex-flow
СкопированоЭто свойство-шорткат для одновременного определения значений свойств flex
и flex
.
.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; }
Как и со всеми шорткатами, с этим стоит быть осторожным. Хоть он и позволяет сэкономить пару строк кода, в случае переопределения одного из значений придётся переписывать свойство целиком, повторяя второе значение, которое не меняется. В таком случае проще было бы иметь два отдельных свойства и менять значения отдельно.
justify-content
Скопировано.container { display: flex; justify-content: space-between;}
.container { display: flex; justify-content: space-between; }
Свойство позволяет выравнивать флекс-элементы внутри флекс-контейнера по основной оси.
Возможные значения:
start
— элементы прижимаются к тому краю, откуда начинается чтение на том языке, на котором отображается сайт.end
— элементы прижимаются к краю, противоположному началу направления чтения на языке сайта.flex
— элементы прижимаются к краю, от которого начинается основная ось.- start flex
— элементы прижимаются к краю, у которого основная ось заканчивается.- end left
— элементы прижмутся к левому краю родителя.right
— элементы прижмутся к правому краю родителя.center
— элементы выстраиваются по центру родителя.space
— крайние элементы прижимаются к краям родителя, оставшиеся выстраиваются внутри контейнера равномерно, так, чтобы между ними были одинаковые отступы.- between space
— свободное пространство делится поровну между элементами и по половине от этой доли размещается по бокам от каждого элемента. Таким образом, между соседними элементами будет равное расстояние, а снаружи крайних элементов — по половине этого расстояния.- around space
— свободное место будет распределено так, чтобы расстояние между любыми двумя элементами было одинаковым и расстояние от крайних элементов до края было таким же.- evenly
Хотя большинство значений поддерживаются основными браузерами, с некоторыми из них могут быть трудности. Поэтому лучше на всякий случай проверяйте поддержку на Can I use.
align-items
Скопировано.container { display: flex; align-items: center;}
.container { display: flex; align-items: center; }
Свойство выравнивания элементов внутри контейнера по поперечной оси.
Возможные значения:
stretch
(значение по умолчанию) — элементы растягиваются вдоль поперечной оси так, чтобы заполнить всего родителя. Это очень удобно, если вы делаете двухколоночный макет. Раньше приходилось при помощи разных костылей добиваться одинаковой высоты, а теперь достаточно сделать контейнер флексом, и колонки по умолчанию будут одной высоты.flex
или- start start
— элементы выстраиваются у начала поперечной оси. Разница между ними лишь в том, что второе значение «уважает» направление чтения выбранного языка.flex
или- end end
— элементы выстраиваются у конца поперечной оси. Разница между первым и вторым значениями аналогична предыдущему пункту.center
— элементы выстраиваются по центру поперечной оси.baseline
— элементы выравниваются по базовой линии текста. «Базовая линия» — baseline — воображаемая линия, проходящая по нижнему краю знаков шрифта (без учёта выносных элементов).
Это может быть сложно понять сразу, поэтому мы сделали демку. Обратите внимание, что вне зависимости от размера шрифта все блоки выравниваются по базовой линии первой строки.
align-content
Скопировано.container { display: flex; align-content: center;}
.container { display: flex; align-content: center; }
Свойство распределяет свободное пространство по поперечной оси между рядами флекс-элементов. Предположим, у вас 11 элементов в 3 рядах. Если размер родителя по поперечной оси позволяет, то при помощи align
можно распределять строчки элементов: по верхнему краю, по нижнему, по центру или равномерно.
Не имеет видимого значения, если элементы располагаются в один ряд.
Возможные значения:
stretch
(значение по умолчанию) — ряды растягиваются одинаково, так, чтобы занять всё доступное пространство родителя.flex
/- start start
— все ряды располагаются у начала поперечной оси. Первое значение не зависит от направления чтения текущего языка, в отличие от второго.flex
/- end end
— все ряды располагаются у конца поперечной оси.end
«уважает» направление чтения текущего языка.center
— ряды выравниваются по центру родителя.space
— первый ряд прижимается к началу поперечной оси, последний — к концу поперечной оси, а остальные располагаются так, чтобы свободное пространство было поделено на отступы между ними равномерно.- between space
— отступы у каждого ряда равнозначны отступам у любого другого ряда.- around space
— отступы между рядами и от краёв родителя одинаковые.- evenly
gap
СкопированоС помощью этого свойства можно с лёгкостью задавать отступы между строками и столбцами.
Является краткой записью свойств row
и column
.
Может иметь одно или два значения. Если указано только одно, то column
автоматически равен row
. Если указаны два значения, то первое будет задавать отступы между рядами (row
), а второе — между колонками (column
).
Значения можно указывать в любых доступных единицах измерения, включая проценты.
Допускается использование функции calc
.
.container { display: flex; gap: 30px calc(10rem - 10px);}
.container { display: flex; gap: 30px calc(10rem - 10px); }
Свойства флекс-элемента
Скопированоorder
Скопировано.container { display: flex;}.item { order: 3;}
.container { display: flex; } .item { order: 3; }
При помощи свойства order
можно менять порядок отображения флекс-элементов внутри флекс-контейнера.
По умолчанию элементы отображаются в том порядке, в котором они расположены в разметке, а значение свойства order
равно 0.
Значение задаётся в виде целого отрицательного или положительного числа. Элементы встают по возрастающей.
flex-grow
Скопировано.container { display: flex;}.item { flex-grow: 1;}
.container { display: flex; } .item { flex-grow: 1; }
Это свойство указывает, может ли вырастать флекс-элемент при наличии свободного места, и насколько. По умолчанию значение равно 0. Значением может быть любое положительное целое число (включая 0).
Если у всех флекс-элементов будет прописано flex
, то свободное пространство в контейнере будет равномерно распределено между всеми.
Если при этом одному из элементов мы зададим flex
, то он постарается занять в два раза больше свободного места, чем его соседи.
flex-shrink
Скопировано.container { display: flex;}.item { flex-shrink: 3;}
.container { display: flex; } .item { flex-shrink: 3; }
Свойство flex
полностью противоположно свойству flex
. Если в контейнере не хватает места для расположения всех элементов без изменения размеров, то свойство flex
указывает, в каких пропорциях элемент будет уменьшаться.
Чем больше значение у этого свойства, тем быстрее элемент будет сжиматься по сравнению с соседями, имеющими меньшее значение.
Значение по умолчанию — 1. Значением может быть любое целое положительное число (включая 0).
Два предыдущих свойства работают с пропорциональным разделением пространства, не с конкретными размерами. Они довольно непростые, даже опытный разработчик не всегда знает, как они в точности работают. Загляните в конец статьи, если хотите подробнее почитать о каждом из них.
flex-basis
Скопировано.container { display: flex;}.item { flex-basis: 250px;}
.container { display: flex; } .item { flex-basis: 250px; }
Свойство flex
указывает на размер элемента до того, как свободное место будет распределено (см. flex-grow).
Значением может быть размер в любых относительных или абсолютных единицах: 20rem
, 5vw
, 250px
. А также можно использовать ключевое слово auto
(значение по умолчанию). В этом случае при расчёте размера элемента будут приниматься во внимание значения свойств width
, max
, min
или аналогичные свойства высоты, в зависимости от того, в каком направлении идёт основная ось.
Если никакие размеры не заданы, а свойству flex
установлено значение auto
, то элемент занимает столько пространства, сколько нужно для отображения контента.
flex
Скопировано.container { display: flex;}.item { flex: 1 1 auto;}
.container { display: flex; } .item { flex: 1 1 auto; }
Свойство-шорткат, с помощью которого можно указать значение трёх свойств одновременно: flex
, flex
и flex
. Первое значение является обязательным, остальные опциональны.
Значение по умолчанию: 0 1 auto
, что расшифровывается как flex
, flex
, flex
.
Возможные значения:
/* 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
Скопировано.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
На практике
Скопированосоветует Скопировано
Свойство margin
со значением auto
позволяет очень гибко управлять выравниванием флекс-элементов. Например, если необходимо, чтобы логотип и заголовок были в левой части контейнера, а кнопка меню прижата к правой части, то достаточно задать кнопке меню значение margin
. В этом случае отступ займёт всё свободное пространство флекс-контейнера и элемент с кнопкой меню окажется прижат к правой части. Отличие от justify
здесь в том, что нет необходимости в дополнительной обёртке для логотипа и заголовка. Также можно задать нескольким элементам свойство margin
, в этом случае всё свободное пространство контейнера разделится на равные части между отступами элементов, у которых задано это свойство. Данный приём расширяет ту функциональность, которую нам даёт свойство justify
, мы можем задавать отступы только между необходимыми элементами, а не всеми сразу.
советует Скопировано
Во время работы стоит быть особенно внимательным со свойствами, которые меняют внешнее расположение элементов внутри flex-контейнера: например flex
или column
, а также со свойством order
.
Дело в том, что контент меняет своё расположение только визуально, CSS-свойствами, а значит, в теле сайта элементы окажутся в том порядке, в котором вы их расположили в HTML-файле. Позаботьтесь о людях, которые пользуются скринридерами, и не меняйте положение элементов на странице CSS-свойствами без крайней необходимости.
Цель крутого фронтендера — решать задачи бизнеса, а не писать много кода. Центрирование блока внутри родителя можно сократить до двух строк:
- Родителя сделать флекс-контейнером.
- Дочернему элементу задать
margin
.: auto
Ждём сокращения кода до одной строки =)
советует Скопировано
🛠 Раньше было затруднительно прижать футер к нижнему краю экрана вне зависимости от количества контента на странице. Приходилось идти на всякие ухищрения и городить костыли. Теперь с появлением флексов всё стало просто.
Оборачиваем всю страницу в блок, делаем его флекс-контейнером, внутрь вкладываем хэдер, мейн и футер. Родителю задаём flex
чтобы блоки встали друг под другом, а не в ряд, и min
, чтобы он занимал как минимум всю высоту экрана. Мейну задаём flex
, и вуаля! Центральный блок страницы будет всегда растягиваться на всё доступное свободное пространство. Из-за этого футер всегда будет прижиматься к нижнему краю страницы. При этом, если контента в мейне будет больше чем на один экран, то он растянется и подстроится, ничего не сломается.
🛠 Частой проблемой в вёрстке до появления флексбоксов было вертикальное выравнивание блока внутри родителя. Использовались хаки с трансформом, отступами, высотой строки и прочие костыли.
Теперь же всё делается в три строки:
- Родителя делаем флекс-контейнером.
- Задаём ему выравнивание по основной оси по центру
justify
.- content : center - Задаём ему выравнивание по поперечной оси по центру
align
.- items : center
Получаем выровненный по центру вложенный блок.
На собеседовании
Скопировано отвечает
СкопированоГриды являются лучшим выбором, когда у вас есть сложные проекты, требующие вёрстки с использованием двумерной компоновки. Эта система позволяет создавать вёрстку с сложным дизайном, который легко обслуживается и требует меньше усилий при поддержке и масштабировании. Кроме того, свойство gap
упрощает определение отступов между элементами и использование его для создания перекрывающихся элементов. Если вы работаете над проектом впервые и хотите создавать структуру и дизайн будущей вёрстки с помощью гридов, то эта система будет очень полезной.
Во всех остальных случаях можно смело использовать флексбоксы.