Время на прочтение
11 мин
Количество просмотров 452K
Полное руководство по CSS flexbox. Это полное руководство объясняет все о flexbox, сосредотачиваясь на всех возможных свойствах для родительского элемента (контейнер flex) и дочерних элементов (элементы flex). Оно также включает в себя историю, демонстрации, шаблоны и таблицу поддержки браузеров.
Background
Модуль Flexbox Layout (Flexible Box) (W3C Candidate Recommendation от октября 2017 г.) направлен на обеспечение более эффективного способа размещения, выравнивания и распределения пространства между элементами в контейнере, даже если их размер неизвестен и / или динамичен (Flex значит «гибкий»).
Основная идея flex layout состоит в том, чтобы дать контейнеру возможность изменять ширину / высоту его элементов (и порядок), чтобы наилучшим образом заполнить доступное пространство (главным образом, для отображения на всех типах устройств с любым размером экрана). Flex контейнер расширяет элементы, чтобы заполнить доступное свободное пространство, или сжимает их, чтобы предотвратить переполнение.
Наиболее важно то, что макет flexbox не зависит от направления, в отличие от обычных макетов (block на вертикальной основе и inline на горизонтальной основе). Хотя они хорошо работают для страниц, им не хватает гибкости (без каламбура :-)) для поддержки больших или сложных приложений (особенно когда речь идет об изменении ориентации, изменении размера, растяжении, сжатии и т.д.).
Примечание: Flexbox layout наиболее подходит для компонентов приложения и мелкомасштабных макетов, а Grid layout предназначен для макетов большего масштаба.
Основы и терминология
Поскольку flexbox — это целый модуль, а не одно свойство, он включает в себя множество элементов с набором свойств. Некоторые из них предназначены для установки в контейнере (родительский элемент принято называть «flex контейнер»), в то время как другие предназначены для установки в дочерних элементах (так называемые «flex элементы»).
Если «обычная» компоновка основана как на блочном, так и на inline направлениях, flex layout основана на «направлениях flex-flow». Пожалуйста, посмотрите на этот рисунок из спецификации, объясняющий основную идею гибкого макета.
Элементы будут расположены либо в направлении главной оси (main axis от main-start до main-end) или в направлении поперечной оси (cross axis от cross-start до cross-end).
- main axis — главная ось flex контейнера — это основная ось, вдоль которой располагаются flex элементы. Будьте внимательны, эта ось не обязательно горизонтальная; это зависит от flex-direction свойства (см. ниже).
- main-start | main-end — flex элементы помещаются в контейнер, начиная с main-start и заканчивая main-end.
- main size — ширина или высота flex элемента, в зависимости от того, что находится в основном измерении. Определяется основным размером flex элементов т.е. свойством ‘width’ или ‘height’, в зависимости от того, что находится в основном измерении.
- cross axis — ось перпендикулярная главной оси, называется поперечной осью. Её направление зависит от направления главной оси.
- cross-start | cross-end — flex строки заполняются элементами и помещаются в контейнер, начиная от cross-start flex контейнера по направлению к cross-end.
- cross size — ширина или высота flex элемента. В зависимости от css свойства flex-direction, это ширина или высота элемента. Это всегда поперечный размер flex элементов.
Свойства для Родителя (flex контейнер)
display
Определяет flex контейнер; inline или block в зависимости от заданного значения. Включает flex контекст для всех потомков первого уровня.
.container {
display: flex; /* or inline-flex */
}
Имейте в виду:
Обратите внимание, что CSS-столбцы columns не влияют на flex контейнер.
flex-direction
Устанавливает основную ось, таким образом определяя направление flex элементов, помещаемых в flex контейнер. Flexbox — это (помимо дополнительной упаковки) концепция однонаправленного макета. Думайте о flex элементах, как о первичных раскладках в горизонтальных рядах или вертикальных столбцах.
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row (по умолчанию): слева направо в ltr; справа налево в rtl
- row-reverse справа налево ltr; слева направо в rtl
- column: так же, как и row но сверху вниз
- column-reverse: то же самое, row-reverse но снизу вверх
flex-wrap
По умолчанию гибкие элементы будут пытаться уместиться на одной строке. Вы можете изменить это и позволить элементам переходить на новую строку по мере необходимости с помощью этого свойства.
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
- nowrap (по умолчанию): все flex элементы будут в одной строке
- wrap: flex-элементы будут перенесены на несколько строк сверху вниз.
- wrap-reverse: flex-элементы будут перенесены на несколько строк снизу вверх.
Посмотреть визуальные демоверсии поведения flex-wrap можно здесь.
flex-flow (Применяется к: родительскому элементу flex-контейнера)
Это сокращение для flex-direction и flex-wrap свойств, которые вместе определяют основные и поперечные оси flex контейнера. Значением по умолчанию является row nowrap.
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
justify-content
Это свойство определяет выравнивание вдоль главной оси. Оно помогает распределить дополнительный остаток свободного пространства, когда-либо все flex элементы в строке негибкие, либо гибкие, но достигли своего максимального размера. Это также обеспечивает некоторый контроль над выравниванием элементов, когда они переполняют линию.
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}
- flex-start (по умолчанию): элементы сдвинуты в начало flex-direction направления.
- flex-end: элементы сдвинуты ближе к концу flex направления.
- start: элементы сдвинуты к началу writing-mode направления.
- end: элементы сдвинуты в конце writing-mode направления.
- left: элементы сдвинуты по направлению к левому краю контейнера, если это не имеет смысла flex-direction, тогда он ведет себя как start.
- right: элементы сдвинуты по направлению к правому краю контейнера, если это не имеет смысла flex-direction, тогда он ведет себя как start.
- center: элементы центрированы вдоль линии
- space-between: элементы равномерно распределены по линии; первый элемент находится в начале строки, последний элемент в конце строки
- space-around: элементы равномерно распределены по линии с одинаковым пространством вокруг них. Обратите внимание, что визуально пространства не равны, так как все элементы имеют одинаковое пространство с обеих сторон. Первый элемент будет иметь одну единицу пространства напротив края контейнера, но две единицы пространства между следующим элементом, потому что у следующего элемента есть свой собственный интервал, который применяется.
- space-evenly: элементы распределяются таким образом, чтобы расстояние между любыми двумя элементами (и расстояние до краев) было одинаковым.
Обратите внимание, что поддержка браузером этих значений имеет свои нюансы. Например, space-between никогда не получал поддержку Edge, а start / end / left / right еще нет в Chrome. В MDN есть подробные графики. Самые безопасные значения это flex-start, flex-end и center.
Есть также два дополнительных ключевых слова, которые вы можете связать с этими значениями: safe и unsafe. Использование safe гарантирует, что как бы вы ни занимались этим типом позиционирования, вы не сможете расположить элемент таким образом, чтобы он отображался за пределами экрана (например, сверху) так, чтобы содержимое тоже не могло быть прокручено (это называется «потеря данных»).
align-items
Это свойство определяет поведение по умолчанию того, как flex элементы располагаются вдоль поперечной оси на текущей линии. Думайте об этом как о justify-content версии для поперечной оси (перпендикулярной главной оси).
.container {
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}
- stretch (по умолчанию): растягивать, чтобы заполнить контейнер (все еще соблюдаются min-width / max-width)
- flex-start / start / self-start: элементы размещаются в начале поперечной оси. Разница между ними невелика и заключается в соблюдении flex-direction правил или writing-mode правил.
- flex-end / end / self-end: элементы располагаются в конце поперечной оси. Разница опять-таки тонкая и заключается в соблюдении flex-direction или writing-mode правил.
- center: элементы центрированы по поперечной оси
- baseline: элементы выровнены, по их базовой линии
safe и unsafe ключевые слова модификаторов могут быть использованы в сочетании со всеми из этих ключевых слов (хотя это поддерживается не всеми браузерами), это помогает предотвратить выравнивание элементов таким образом, что содержание становится недоступным.
align-content
Это свойство выравнивает линии в пределах flex контейнера, когда есть дополнительное пространство на поперечной оси, подобно тому, как justify-content выравнивает отдельные элементы в пределах главной оси.
Примечание: это свойство не действует, когда есть только одна строка flex элементов.
.container {
align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}
- flex-start / start: элементы, сдвинуты в начало контейнера. Более поддерживаемый flex-start использует, flex-direction в то время как start использует writing-mode направление.
- flex-end / end: элементы, сдвинуты в конец контейнера. Более поддерживаемый flex-end использует flex-direction в то время как end использует writing-mode направление.
- center: элементы выровнены по центру в контейнере
- space-between: элементы равномерно распределены; первая строка находится в начале контейнера, а последняя — в конце
- space-around: элементы равномерно распределены с равным пространством вокруг каждой строки
- space-evenly: элементы распределены равномерно, вокруг них одинаковое пространство
- stretch (по умолчанию): линии растягиваются, чтобы занять оставшееся пространство
safe и unsafe ключевые слова модификаторов могут быть использованы в сочетании со всеми из этих ключевых слов (хотя это поддерживается не всеми браузерами), это помогает предотвратить выравнивание элементов таким образом, что содержание становится недоступным.
Свойства для первых дочерних элементов(flex элементы)
order
По умолчанию flex элементы располагаются в исходном порядке. Однако свойство order управляет порядком их появления в контейнере flex.
.item {
order: <integer>; /* default is 0 */
}
flex-grow
Это свойство определяет способность flex элемента растягиваться в случае необходимости. Оно принимает значение от нуля, которое служит пропорцией. Это свойство, какое количество доступного пространства внутри гибкого контейнера должен занимать элемент.
Если для всех элементов flex-grow установлено значение 1, оставшееся пространство в контейнере будет равномерно распределено между всеми дочерними элементами. Если один из дочерних элементов имеет значение 2, этот элемент займет в два раза больше места, чем остальные (или попытается, по крайней мере).
.item {
flex-grow: <number>; /* default 0 */
}
Отрицательные числа не поддерживаются.
flex-shrink
Это свойство определяет способность гибкого элемента сжиматься при необходимости.
.item {
flex-shrink: <number>; /* default 1 */
}
Отрицательные числа не поддерживаются.
flex-basis
Это свойство определяет размер элемента по умолчанию перед распределением оставшегося пространства. Это может быть длина (например, 20%, 5rem и т.д.) Или ключевое слово. Ключевое слово auto означает «смотри на мое width или height свойство». Ключевое слово content означает «размер на основе содержимого элемента» — это ключевое слово все еще не очень хорошо поддерживается, так что трудно проверить что для него используется max-content, min-content или fit-content.
.item {
flex-basis: <length> | auto; /* default auto */
}
Если установлено значение 0, дополнительное пространство вокруг содержимого не учитывается. Если установлено значение auto, дополнительное пространство распределяется в зависимости от его flex-grow значения.
Смотрите этот рисунок.
flex
Это сокращение для использования flex-grow, flex-shrink и flex-basis вместе. Второй и третий параметры (flex-shrink и flex-basis) являются необязательными. По умолчанию это 0 1 auto.
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
Рекомендуется использовать это сокращенное свойство, а не устанавливать отдельные свойства. Это сокращение разумно устанавливает другие значения.
align-self
Это свойство позволяет переопределить выравнивание по умолчанию (или указанное с помощью align-items) для отдельных элементов flex.
Пожалуйста, смотрите align-items свойство, чтобы понять доступные значения.
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
Обратите внимание что свойства float, clear и vertical-align не влияют на flex элементы.
Примеры
Давайте начнем с очень простого примера, решающего почти ежедневную проблему: идеальное центрирование. Самое простое решение для этой задачи — это использовать flexbox.
.parent {
display: flex;
height: 300px; /* Или что угодно */
}
.child {
width: 100px; /* Или что угодно */
height: 100px; /* Или что угодно */
margin: auto; /* Магия! */
}
Так происходит благодаря тому, что свойство вертикального выравнивания margin установленное в auto во flex контейнере, поглощает дополнительное пространство. Таким образом, установка margin в auto сделает объект идеально отцентрированным по обеим осям.
Теперь давайте используем еще несколько свойств. Рассмотрим список из 6 элементов, все с фиксированными размерами, но могут быть и авторазмеры. Мы хотим, чтобы они были равномерно распределены по горизонтальной оси, чтобы при изменении размера браузера все масштабировалось хорошо и без медиа запросов.
.flex-container {
/* Сначала мы создаем flex контекст */
display: flex;
/* Затем мы определяем flex-direction и разрешаем элементам переходить на новые строки
* Запомните, что это то же самое что и:
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
/* Затем мы определяем, как распределяется оставшееся пространство */
justify-content: space-around;
}
Готово. Все остальное — это просто стайлинг.
Если изменить разрешение экрана ли масштаб, то будет так:
Давайте попробуем что-нибудь еще. Представьте, что у нас есть выровненные по правому краю элементы навигации в верхней части нашего веб-сайта, но мы хотим, чтобы они были выровнены по ширине на экранах среднего размера и располагались в один столбец на небольших устройствах. Это достаточно просто.
/* Большие экраны */
.navigation {
display: flex;
flex-flow: row wrap;
/* Это выровняет элементы по конечной части линии на главной оси */
justify-content: flex-end;
}
/* Средние экраны */
@media all and (max-width: 800px) {
.navigation {
/* На экранах среднего размера мы центрируем элементы, равномерно распределяя пустое пространство вокруг элементов */
justify-content: space-around;
}
}
/* Маленькие экраны */
@media all and (max-width: 500px) {
.navigation {
/* На маленьких экранах мы больше не используем направление строки, а используем столбец */
flex-direction: column;
}
}
Большие экраны
Средние экраны
Маленькие экраны
Давайте попробуем что-то еще лучше, играя с гибкостью flex элементов! Как насчет 3-колоночного макета в полную высоту страницы с хедором и футером. И не зависит от исходного порядка элементов.
.wrapper {
display: flex;
flex-flow: row wrap;
}
/* Мы говорим, что все элементы имеют ширину 100%, через flex-base */
.wrapper > * {
flex: 1 100%;
}
/* Мы используем исходный порядок для первого мобильно варианта
* 1. header
* 2. article
* 3. aside 1
* 4. aside 2
* 5. footer
*/
/* Средние экраны */
@media all and (min-width: 600px) {
/* Мы говорим обеим боковым панелям встать в одну строку */
.aside { flex: 1 auto; }
}
/* Большие экраны */
@media all and (min-width: 800px) {
/* Мы инвертируем порядок первой боковой панели и основной и говорим главному элементу, чтобы он занимал вдвое большую ширину, чем две другие боковые панели
*/
.main { flex: 2 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
Большие экраны
Средние экраны
Маленькие экраны
Префикс для Flexbox
Flexbox требует префикса для лучшей поддержки в разных браузерах. Он не только включает в себя предварительные настройки с префиксом вендора, в нем есть совершенно разные имена свойств и значений. Это связано с тем, что спецификации Flexbox со временем менялись, существуют «старые», «tweener» и «новые» версии.
Возможно, лучший способ справиться с этим — написать новый (и последний) синтаксис и запустить свой CSS через Autoprefixer, который очень хорошо справляется с fallback.
Кроме того, вот Sass @mixin, чтобы помочь с некоторыми префиксами, который также дает вам представление о том, что нужно сделать:
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}
Ошибки
Flexbox, конечно, не без ошибок. Лучшая коллекция из них, которую я видел, — это Flexbugs Филипа Уолтона и Грега Витворта. Это репозиторий с открытым исходным кодом для отслеживания всех из них, поэтому я думаю, что лучше всего просто сослаться на него.
Поддержка в браузерах
Разбита по «версии» flexbox:
- (new) означает недавний синтаксис из спецификации (например display: flex;)
- (tweener) означает странный неофициальный синтаксис с 2011 года (например display: flexbox;)
- (old) означает старый синтаксис с 2009 года (например display: box;)
Blackberry Browser 10+ поддерживает новый синтаксис.
Для получения дополнительной информации о том, как смешивать синтаксисы, чтобы получить лучшую поддержку браузера, пожалуйста, обратитесь к этой статье (CSS-хитрости) или этой статье (DevOpera).
Table of contents
- Background
- Basics and terminology
- Flexbox properties
- Prefixing Flexbox
- Examples
- Flexbox tricks
- Browser support
- Bugs
- Related properties
- More information
- More sources
Get the poster!
Reference this guide a lot? Here’s a high-res image you can print!
Background
The Flexbox Layout
(Flexible Box) module (a W3C Candidate Recommendation as of October 2017) aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word “flex”).
The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space or shrinks them to prevent overflow.
Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).
Note: Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the Grid layout is intended for larger scale layouts.
Basics and terminology
Since flexbox is a whole module and not a single property, it involves a lot of things including its whole set of properties. Some of them are meant to be set on the container (parent element, known as “flex container”) whereas the others are meant to be set on the children (said “flex items”).
If “regular” layout is based on both block and inline flow directions, the flex layout is based on “flex-flow directions”. Please have a look at this figure from the specification, explaining the main idea behind the flex layout.
Items will be laid out following either the main axis
(from main-start
to main-end
) or the cross axis (from cross-start
to cross-end
).
- main axis – The main axis of a flex container is the primary axis along which flex items are laid out. Beware, it is not necessarily horizontal; it depends on the
flex-direction
property (see below). - main-start | main-end – The flex items are placed within the container starting from main-start and going to main-end.
- main size – A flex item’s width or height, whichever is in the main dimension, is the item’s main size. The flex item’s main size property is either the ‘width’ or ‘height’ property, whichever is in the main dimension.
- cross axis – The axis perpendicular to the main axis is called the cross axis. Its direction depends on the main axis direction.
- cross-start | cross-end – Flex lines are filled with items and placed into the container starting on the cross-start side of the flex container and going toward the cross-end side.
- cross size – The width or height of a flex item, whichever is in the cross dimension, is the item’s cross size. The cross size property is whichever of ‘width’ or ‘height’ that is in the cross dimension.
Flexbox properties
Properties for the Parent
(flex container)
display
This defines a flex container; inline or block depending on the given value. It enables a flex context for all its direct children.
.container {
display: flex; /* or inline-flex */
}
Note that CSS columns have no effect on a flex container.
flex-direction
This establishes the main-axis, thus defining the direction flex items are placed in the flex container. Flexbox is (aside from optional wrapping) a single-direction layout concept. Think of flex items as primarily laying out either in horizontal rows or vertical columns.
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
row
(default): left to right inltr
; right to left inrtl
row-reverse
: right to left inltr
; left to right inrtl
column
: same asrow
but top to bottomcolumn-reverse
: same asrow-reverse
but bottom to top
flex-wrap
By default, flex items will all try to fit onto one line. You can change that and allow the items to wrap as needed with this property.
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap
(default): all flex items will be on one linewrap
: flex items will wrap onto multiple lines, from top to bottom.wrap-reverse
: flex items will wrap onto multiple lines from bottom to top.
There are some visual demos of flex-wrap
here.
flex-flow
This is a shorthand for the flex-direction
and flex-wrap
properties, which together define the flex container’s main and cross axes. The default value is row nowrap
.
.container {
flex-flow: column wrap;
}
justify-content
This defines the alignment along the main axis. It helps distribute extra free space leftover when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line.
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}
flex-start
(default): items are packed toward the start of the flex-direction.flex-end
: items are packed toward the end of the flex-direction.start
: items are packed toward the start of thewriting-mode
direction.end
: items are packed toward the end of thewriting-mode
direction.left
: items are packed toward left edge of the container, unless that doesn’t make sense with theflex-direction
, then it behaves likestart
.right
: items are packed toward right edge of the container, unless that doesn’t make sense with theflex-direction
, then it behaves likeend
.center
: items are centered along the linespace-between
: items are evenly distributed in the line; first item is on the start line, last item on the end linespace-around
: items are evenly distributed in the line with equal space around them. Note that visually the spaces aren’t equal, since all the items have equal space on both sides. The first item will have one unit of space against the container edge, but two units of space between the next item because that next item has its own spacing that applies.space-evenly
: items are distributed so that the spacing between any two items (and the space to the edges) is equal.
Note that that browser support for these values is nuanced. For example, space-between
never got support from some versions of Edge, and start/end/left/right aren’t in Chrome yet. MDN has detailed charts. The safest values are flex-start
, flex-end
, and center
.
There are also two additional keywords you can pair with these values: safe
and unsafe
. Using safe
ensures that however you do this type of positioning, you can’t push an element such that it renders off-screen (e.g. off the top) in such a way the content can’t be scrolled too (called “data loss”).
align-items
This defines the default behavior for how flex items are laid out along the cross axis on the current line. Think of it as the justify-content
version for the cross-axis (perpendicular to the main-axis).
.container {
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}
stretch
(default): stretch to fill the container (still respect min-width/max-width)flex-start
/start
/self-start
: items are placed at the start of the cross axis. The difference between these is subtle, and is about respecting theflex-direction
rules or thewriting-mode
rules.flex-end
/end
/self-end
: items are placed at the end of the cross axis. The difference again is subtle and is about respectingflex-direction
rules vs.writing-mode
rules.center
: items are centered in the cross-axisbaseline
: items are aligned such as their baselines align
The safe
and unsafe
modifier keywords can be used in conjunction with all the rest of these keywords (although note browser support), and deal with helping you prevent aligning elements such that the content becomes inaccessible.
align-content
This aligns a flex container’s lines within when there is extra space in the cross-axis, similar to how justify-content
aligns individual items within the main-axis.
Note: This property only takes effect on multi-line flexible containers, where flex-wrap
is set to either wrap
or wrap-reverse
). A single-line flexible container (i.e. where flex-wrap
is set to its default value, no-wrap
) will not reflect align-content
.
.container {
align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}
normal
(default): items are packed in their default position as if no value was set.flex-start
/start
: items packed to the start of the container. The (more supported)flex-start
honors theflex-direction
whilestart
honors thewriting-mode
direction.flex-end
/end
: items packed to the end of the container. The (more support)flex-end
honors theflex-direction
while end honors thewriting-mode
direction.center
: items centered in the containerspace-between
: items evenly distributed; the first line is at the start of the container while the last one is at the endspace-around
: items evenly distributed with equal space around each linespace-evenly
: items are evenly distributed with equal space around themstretch
: lines stretch to take up the remaining space
The safe
and unsafe
modifier keywords can be used in conjunction with all the rest of these keywords (although note browser support), and deal with helping you prevent aligning elements such that the content becomes inaccessible.
gap, row-gap, column-gap
The gap
property explicitly controls the space between flex items. It applies that spacing only between items not on the outer edges.
.container {
display: flex;
...
gap: 10px;
gap: 10px 20px; /* row-gap column gap */
row-gap: 10px;
column-gap: 20px;
}
The behavior could be thought of as a minimum gutter, as if the gutter is bigger somehow (because of something like justify-content: space-between;
) then the gap will only take effect if that space would end up smaller.
It is not exclusively for flexbox, gap
works in grid and multi-column layout as well.
Properties for the Children
(flex items)
order
By default, flex items are laid out in the source order. However, the order
property controls the order in which they appear in the flex container.
.item {
order: 5; /* default is 0 */
}
Items with the same order
revert to source order.
flex-grow
This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.
If all items have flex-grow
set to 1
, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2
, that child would take up twice as much of the space either one of the others (or it will try, at least).
.item {
flex-grow: 4; /* default 0 */
}
Negative numbers are invalid.
flex-shrink
This defines the ability for a flex item to shrink if necessary.
.item {
flex-shrink: 3; /* default 1 */
}
Negative numbers are invalid.
flex-basis
This defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword. The auto
keyword means “look at my width or height property” (which was temporarily done by the main-size
keyword until deprecated). The content
keyword means “size it based on the item’s content” – this keyword isn’t well supported yet, so it’s hard to test and harder to know what its brethren max-content
, min-content
, and fit-content
do.
.item {
flex-basis: | auto; /* default auto */
}
If set to 0
, the extra space around content isn’t factored in. If set to auto
, the extra space is distributed based on its flex-grow
value. See this graphic.
flex
This is the shorthand for flex-grow,
flex-shrink
and flex-basis
combined. The second and third parameters (flex-shrink
and flex-basis
) are optional. The default is 0 1 auto
, but if you set it with a single number value, like flex: 5;
, that changes the flex-basis
to 0%, so it’s like setting flex-grow: 5; flex-shrink: 1; flex-basis: 0%;
.
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
It is recommended that you use this shorthand property rather than set the individual properties. The shorthand sets the other values intelligently.
align-self
This allows the default alignment (or the one specified by align-items
) to be overridden for individual flex items.
Please see the align-items
explanation to understand the available values.
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
Note that float
, clear
and vertical-align
have no effect on a flex item.
Prefixing Flexbox
Flexbox requires some vendor prefixing to support the most browsers possible. It doesn’t just include prepending properties with the vendor prefix, but there are actually entirely different property and value names. This is because the Flexbox spec has changed over time, creating an “old”, “tweener”, and “new” versions.
Perhaps the best way to handle this is to write in the new (and final) syntax and run your CSS through Autoprefixer, which handles the fallbacks very well.
Alternatively, here’s a Sass @mixin
to help with some of the prefixing, which also gives you an idea of what kind of things need to be done:
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}
Examples
Let’s start with a very very simple example, solving an almost daily problem: perfect centering. It couldn’t be any simpler if you use flexbox.
.parent {
display: flex;
height: 300px; /* Or whatever */
}
.child {
width: 100px; /* Or whatever */
height: 100px; /* Or whatever */
margin: auto; /* Magic! */
}
This relies on the fact a margin set to auto
in a flex container absorb extra space. So setting a margin of auto
will make the item perfectly centered in both axes.
Now let’s use some more properties. Consider a list of 6 items, all with fixed dimensions, but can be auto-sized. We want them to be evenly distributed on the horizontal axis so that when we resize the browser, everything scales nicely, and without media queries.
.flex-container {
/* We first create a flex layout context */
display: flex;
/* Then we define the flow direction
and if we allow the items to wrap
* Remember this is the same as:
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
/* Then we define how is distributed the remaining space */
justify-content: space-around;
}
Done. Everything else is just some styling concern. Below is a pen featuring this example. Be sure to go to CodePen and try resizing your windows to see what happens.
Let’s try something else. Imagine we have a right-aligned navigation element on the very top of our website, but we want it to be centered on medium-sized screens and single-columned on small devices. Easy enough.
/* Large */
.navigation {
display: flex;
flex-flow: row wrap;
/* This aligns items to the end line on main-axis */
justify-content: flex-end;
}
/* Medium screens */
@media all and (max-width: 800px) {
.navigation {
/* When on medium sized screens, we center it by evenly distributing empty space around items */
justify-content: space-around;
}
}
/* Small screens */
@media all and (max-width: 500px) {
.navigation {
/* On small screens, we are no longer using row direction but column */
flex-direction: column;
}
}
Let’s try something even better by playing with flex items flexibility! What about a mobile-first 3-columns layout with full-width header and footer. And independent from source order.
.wrapper {
display: flex;
flex-flow: row wrap;
}
/* We tell all items to be 100% width, via flex-basis */
.wrapper > * {
flex: 1 100%;
}
/* We rely on source order for mobile-first approach
* in this case:
* 1. header
* 2. article
* 3. aside 1
* 4. aside 2
* 5. footer
*/
/* Medium screens */
@media all and (min-width: 600px) {
/* We tell both sidebars to share a row */
.aside { flex: 1 auto; }
}
/* Large screens */
@media all and (min-width: 800px) {
/* We invert order of first sidebar and main
* And tell the main element to take twice as much width as the other two sidebars
*/
.main { flex: 3 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
Flexbox tricks!
Browser support
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
21* | 28 | 11 | 12 | 6.1* |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
113 | 113 | 4.4 | 7.0-7.1* |
Bugs
Flexbox is certainly not without its bugs. The best collection of them I’ve seen is Philip Walton and Greg Whitworth’s Flexbugs. It’s an open-source place to track all of them, so I think it’s best to just link to that.
Related properties
Almanac
on
Jul 28, 2021
align-content
.element { align-content: space-around; }
Almanac
on
Sep 28, 2022
align-items
.element { align-items: flex-start; }
Almanac
on
Dec 27, 2018
align-self
.box { align-self: flex-end; }
Almanac
on
Aug 30, 2021
column-gap
.example { column-gap: 25px; }
Almanac
on
Oct 15, 2021
display
.element { display: inline-block; }
Almanac
on
Sep 22, 2022
gap
.element { gap: 20px 30px; }
Almanac
on
Mar 2, 2021
justify-items
.element { justify-items: center; }
Almanac
on
Sep 30, 2022
flex
.element { flex: 1 1 100px; }
Almanac
on
Sep 30, 2022
flex-basis
.element { flex-basis: 100px; }
Almanac
on
Aug 4, 2021
flex-direction
.element { flex-direction: column-reverse; }
Almanac
on
Aug 4, 2021
flex-flow
.element { flex-flow: row wrap; }
Almanac
on
Aug 4, 2021
flex-grow
.flex-item { flex-grow: 2; }
Almanac
on
Aug 4, 2021
flex-shrink
.element { flex-shrink: 2; }
Almanac
on
Sep 30, 2022
flex-wrap
.example { flex-wrap: wrap; }
Almanac
on
Sep 22, 2022
justify-content
.element { justify-content: center; }
Almanac
on
Apr 28, 2022
justify-self
.element { justify-self: stretch; }
Almanac
on
Aug 30, 2021
row-gap
.element { row-gap: 2rem; }
More information
- CSS Flexible Box Layout Module Level 1 (W3C)
- A CSS Flexbox Cheatsheet (DigitalOcean)
- Centering Things in CSS With Flexbox (DigitalOcean)
Article
on
Sep 26, 2013
Solved by Flexbox
Article
on
Nov 25, 2013
Flexbox Cheat Sheet
Article
on
Dec 23, 2012
Dive Into Flexbox
Article
on
Oct 23, 2018
Use Cases for Flexbox
Article
on
Feb 14, 2019
Quick! What’s the Difference Between Flexbox and Grid?
Article
on
Feb 23, 2022
Does CSS Grid Replace Flexbox?
Article
on
Jun 25, 2020
Grid for layout, flexbox for components
Article
on
Apr 13, 2016
Should I use Grid or Flexbox?
Article
on
Aug 13, 2016
Don’t Overthink It (Flexbox) Grids
Article
on
Nov 24, 2021
Building Multi-Directional Layouts
Article
on
Jan 6, 2020
How Auto Margins Work in Flexbox
Article
on
Apr 10, 2017
`flex-grow` is weird. Or is it?
Article
on
Oct 18, 2022
Understanding flex-grow, flex-shrink, and flex-basis
Article
on
Feb 18, 2019
IE10-Compatible Grid Auto-Placement with Flexbox
Article
on
Aug 13, 2013
“Old” Flexbox and “New” Flexbox
Article
on
Jun 15, 2013
Using Flexbox: Mixing Old and New for the Best Browser Support
More sources
- CSS Flexible Box Layout Module Level 1 (W3C)
- A CSS Flexbox Cheatsheet (DigitalOcean)
- Centering Things in CSS With Flexbox (DigitalOcean)
- CSS Layout: Flexbox (MDN)
- Use Cases for Flexbox (Smashing Magazine)
Предисловие
Модуль Flexbox Layout (Flexible Box) направлен на то чтобы предоставить более эффективный способ расположения, выравнивания и распределения свободного пространства между элементами в контейнере, даже когда их размер заранее неизвестен и/или динамичен (поэтому слово «flex»).
Основная идея гибкой (flex) разметки заключается в том, чтобы предоставить контейнеру возможность изменять ширину/высоту (и порядок) своих элементов, для того чтобы наилучшим образом заполнить доступное пространство (в основном для размещения на всех типах и размерах экранов). Flexbox контейнер расширяет элементы чтобы заполнить свободное пространство или сжимает их чтобы избежать переполнения.
Самое главное, что Flexbox это направленный агностик в отличии от обычных раскладок (блоков основанных на вертикальном позиционировании и строковых элементов основанных на горизонтальном позиционировании). Не смотря на то что они достаточно хорошо работают, им не хватает гибкости для поддержки больших или сложных приложений (особенно когда речь идёт об изменении ориентации, изменении размеров, растягивании, сжатии и т. д.).
Примечание. Flexbox больше подходит для компонентов приложения и небольших макетов, тогда как CSS Grid предназначен для более масштабных макетов.
Основы и терминология
Так как Flexbox — это целый модуль, а не отдельное свойство, он содержит множество различных вещей, включая целый набор свойств. Некоторые из них предназначены для установки их контейнеру (родительский элемент, известный как «flex-контейнер»), а другие должны устанавливаться дочерним элементам (известные как «flex-элементы»).
Если обычная система компоновки основана на блочных и строковых направлениях, то Flexbox основан на «flex-flow направлениях». Пожалуйста взгляните на этот рисунок из спецификации, объясняющий основную идею Flexbox.
В основном элементы будут располагаться вдоль основной оси (от main-start
к main-end
) или попереченой оси (от cross-start
к cross-end
).
- main axis — это основная ось flex-контейнера, вдоль которой расположены flex-элементы. Берегитесь того, что это не обязательно горизонтальная ось; Она зависит от свойства flex-direction;
- main-start | main-end — flex-элементы размещаются внутри контейнера, начиная с
main-start
и заканчиваяmain-end
; - main size — ширина или высота flex-элемента, в зависимости направления основной оси;
- cross axis — это ось перпендикулярная основной оси, которая называется «поперечной» осью. Её направление зависит от направления основной оси;
- cross-start | cross-end — — flex-элементы размещаются внутри контейнера, начиная с
cross-start
и заканчиваяcross-end
; - cross size — ширина или высота flex-элемента, в зависимости направления поперечной оси;
Поддержка браузерами
CSS Flexible Box Layout Module
Полная поддержка
Частичная поддержка
С префиксом
Не поддерживается
Браузер Blackberry начиная с 10 версии поддерживает новый синтаксис.
Содержание
Свойства для элементов
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
Свойства для родительского элемента
(Flex-контейнера)
display
Определяет flex-контейнер; строковый или блочный зависит от переданного значения. Включает flex-контекст для всех своих прямых, дочерних элементов.
.container {
display: flex; /* или inline-flex */
}
Обратите внимание, что CSS колонки не влияют на flex-контейнер.
flex-direction
Устанавливает основную ось, таким образом определяет направление элементов расположенных в контейнере. Flexbox (помимо опциональной обёртки) представляет собой концепцию однонаправленного макета. Думайте о flex-элементах, прежде всего как горизонтальных строках или вертикальных колонках.
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row (по умолчанию) — слева направо в
ltr
; справа налево вrtl
; - row-reverse — справа налево в
ltr
; слева направо вrtl
; - column — тоже самое что
row
, только сверху вниз; - column-reverse — тоже самое что
row-reverse
, только снизу вверх;
flex-wrap
По умолчанию, элементы будут пытаться заполнить только одну строк. Вы можете изменить это поведение и позволить элементам переноситься на следующую строку, при необходимости.
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
- nowrap (по умолчанию) — все flex-элементы будут расположены на одной строке;
- wrap — flex-элементы будут расположены на нескольких строках, сверху вниз;
- wrap-reverse — flex-элементы будут расположены на нескольких строках, снизу вверх;
flex-flow
Это сокращение для свойств flex-direction и flex-wrap, которые вместе определяют основную и поперечные оси контейнера. По умолчанию row nowrap
.
.container{
flex-flow: <‘flex-direction’> || <‘flex-wrap’>;
}
justify-content
Определяет выравнивание вдоль основной оси. Это помогает распределить свободное пространство, оставшееся после того как все фиксированные и не фиксированные по ширине flex-элементы достигли максимального размера. Оно также помогает осуществлять некоторый контроль над выравниванием элементов, когда они переполняют строку.
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
- flex-start (по умолчанию) — элементы прижимаются к началу строки;
- flex-end — элементы прижимаются к концу строки;
- center — элементы располагаются по центру вдоль строки;
- space-between — элементы размещаются равномерно на линии; первый элемент находится в начале строки, последний элемент находится в конце строки;
- space-around — элементы размещаются равномерно на линии с одинаковым пространством возле них. Обратите внимание, что визуально пространство не одинаковое, так как у всех элементов одинаковое пространство с обеих сторон. У первого элемента будет одна единица пространства со стороны контейнера, но две единицы между ним и следующим элементом, потому что у следующего элемента также по одной единице с двух сторон.
align-items
Это свойство определяет поведение flex-элементов вдоль поперечной оси на текущей строке. Думайте о нём как о justify-content, только для поперечной оси (перпендикулярной основной оси).
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
- flex-start — элементы размещаются в начале поперечной оси;
- flex-end — элементы размещаются в конце поперечной оси;
- center — элементы располагаются по центру поперечной оси;
- baseline — элементы выравниваются по базовой линии;
- stretch (по умолчанию) — растягиваются чтобы заполнить весь контейнер (по-прежнему соблюдают
min-width
/max-width
);
align-content
Примечание. Это свойство не действует, когда есть только одна строка flex-элементов.
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
- flex-start — строки располагаются в начале контейнера;
- flex-end — строки располагаются в конце контейнера;
- center — строки размещаются по центру контейнера;
- space-between — строки распределяются равномерно, первая строка располагается в начале контейнера, а последняя строка в конце;
- space-around — строки распределяются равномерно, с одинаковым расстоянием между ними;
- stretch (по умолчанию) — строки растягиваются по всей ширине, чтобы занять оставшееся пространство;
Свойства для дочерних элементов
(Flex элементов)
order
По умолчанию, все элементы располагаются в исходном для них порядке. Однако, свойство order
управляет порядком, в котором располагаются элементы внутри контейнера.
.item {
order: <integer>;
}
flex-grow
Свойство определяет возможность элемента увеличиваться в размере, при необходимости. Оно принимает безразмерное значение в качестве пропорции, которое определяет какое количество свободного пространства внутри контейнера должен занимать элемент.
Если у всех элементов свойство flex-grow
установлено в 1
, то свободное пространство внутри контейнера будет равномерно распределено между всеми элементами. Если у одного из элементов значение установлено в 2
, то элемент будет занимать в два раза больше пространства, чем остальные (по крайней мере, попытается).
.item {
flex-grow: <number>; /* по умолчанию 0 */
}
Нельзя указывать отрицательные числа.
flex-shrink
Это свойство определяет возможность элемента уменьшаться в размере, при необходимости.
.item {
flex-shrink: <number>; /* по умолчанию 1 */
}
Нельзя указывать отрицательные числа.
flex-basis
Определяет размер элемента по умолчанию, до распределения оставшегося пространства. Это может быть длина (20%, 5rem и т.д.) или ключевое слово. Ключевое слово auto
означает «выглядеть как моё свойство width
или height
«. Ключевое слово content
означает что «размер основан на содержимом элемента» — это ключевое слово пока не очень хорошо поддерживается, поэтому его трудно проверить, а ещё труднее узнать что делают его братья min-content
, max-content
и fit-content
.
.item {
flex-basis: <length> | auto; /* по умолчанию auto */
}
Если установить значение 0
, то дополнительное пространство вокруг содержимого не будет учитываться. Если установить auto
, дополнительное пространство будет распределяться на основе значения flex-grow. Смотрите этот рисунок.
flex
Это сокращение для flex-grow, flex-shrink и flex-basis. Второй и третий параметры (flex-shrink
и flex-basis
) не обязательны. Значение по умолчанию установлено в 0 1 auto
.
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
Рекомендуется использовать это сокращённое свойство, а не указывать значения индивидуально. Короткая комбинация задаёт другие значения разумно.
align-self
Это свойство позволяет переопределить выравнивание по умолчанию (или заданное с помощью свойства align-items) для отдельных flex-элементов.
Пожалуйста посмотрите на объяснение свойства align-items, чтобы понимать доступные значения.
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
Обратите внимание, что float
, clear
и vertical-align
не оказывают никакого влияния на flex-элемент.
Примеры
Давайте начнём с самого простого примера, решающего задачу, которая возникает почти каждый день: идеальное центрирование. Не может быть ничего проще, если вы используете Flexbox.
.parent {
display: flex;
height: 300px;
}
.child {
width: 100px;
height: 100px;
margin: auto;
}
Это зависит от того, что margin
, установленный в auto
у flex-контейнера, поглощает дополнительное пространство. Таким образом, установка вертикального margin
в auto
у элемента, сделает элемент идеально центрированным по обеим осям.
Теперь давайте используем ещё несколько свойств. Рассмотрим список из 6 элементов, все с фиксированным размером в эстетическом отношении, но они могут быть автоматическими. Мы хотим, чтобы они были равномерно распределены вдоль горизонтальной оси и чтобы при изменении размера браузера всё было в порядке (без медиа-запросов!).
.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
}
Готово! Всё остальное, это лишь некоторые проблемы дизайна. Ниже приведён пример на CodePen, обязательно зайдите туда и попробуйте изменить размер окон, чтобы посмотреть что произойдёт.
Давайте попробуем что-нибудь ещё. Представьте, что у нас есть навигация расположенная по правому краю в самой верхней части экрана, но мы хотим чтобы она располагалась по центру на экранах среднего размера и была в одну колонку на маленьких экранах. Проще простого.
.navigation {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
}
@media all and (max-width: 800px) {
.navigation {
justify-content: space-around;
}
}
@media all and (max-width: 500px) {
.navigation {
flex-direction: column;
}
}
Давайте попробуем сделать что-нибудь ещё лучше, играясь с гибкостью наших flex-элементов! Как насчёт трёхколоночного mobile-first макета с шапкой и футером на всю ширину экрана, и чтобы не было зависимости от исходного порядка элементов.
.wrapper {
display: flex;
flex-flow: row wrap;
}
.header, .main, .nav, .aside, .footer {
flex: 1 100%;
}
@media all and (min-width: 600px) {
.aside { flex: 1 auto; }
}
@media all and (min-width: 800px) {
.main { flex: 2 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
Связанные свойства
Ошибки
Безусловно Flexbox не без ошибок. Лучшая коллекция, которую я видел представлена Philip Walton и Greg Whitworth’s Flexbugs. Это Open Source место для отслеживания всех ошибок, поэтому я думаю, что лучше всего просто оставить ссылку.
Модель верстки известная как Flexbox (флексы), становится все популярнее. В первую очередь за счет удобного использования при создании каркасов и верстки отдельных элементов HTML страницы. Во вторую, за счет совершенно новых возможностей. В этой статье я попробую разобраться во всех тонкостях Flexbox, сделать своего рода документацию (шпаргалку) по флексам и доступно поделиться знаниями с вами.
Если говорить коротко про документацию флексов, то верстка с Flexbox дает нам простые решения некогда непростых задач. Например, когда нужно выровнять элемент по вертикали, или прижать подвал к низу экрана, или просто вставить несколько блоков в один ряд, так чтобы они занимали все свободно пространство. Подобные задачи решаются и без flex. Но как правило, эти решения больше похожи на «костыли», и это еще больше усложняется когда нужно сверстать адаптивный под мобильные устройства макет. Тогда как с flexbox такие задачи решаются элегантно и именно так, как задумывает flex-модель (без добавления вспомогательных стилей и прочего).
CSS Flexible Box Layout Module (CSS модуль для макетов с гибкими блоками), коротко flexbox (Флексбокс), создана, чтобы убрать недостатки при создании самых разных HTML конструкций, в том числе адаптированных под разную ширину и высоту, и сделать верстку логичной и простой. А логичный подход, как правило работает в неожиданных местах, там где результат не проверялся — логика наше все!
Flexbox позволяет элегантно контролировать самые разные параметры элементов внутри контейнера: направление, порядок, ширину, высоту, выравнивание вдоль и поперек, распределение свободного места, растяжение и сжатие элементов.
Базовые знания
FlexBox состоит из Контейнера и его Дочерних элементов (items) (гибких элементов).
-
Главная ось — главное направление движения элементов внутри контейнера. Направление главной оси можно изменить с помощью свойства flex-direction. Обратите внимание, что при смене осей, меняются только направления движения блоков внутри, а начало, конец и размер контейнера остаются прежними.
-
Начало и конец главной оси — элементы располагаются от начала и до конца контейнера.
-
Поперечная ось — направление движения элементов, когда они не умещаются в контейнер по направлению главной оси. Поперечная ось всегда перпендикулярна (⊥) главной.
-
Начало и конец поперечной оси — по поперечной оси заполняются ряды от начала и до конца контейнера. В каждом таком ряду располагаются элементы (читайте ниже).
- Размер (главный и поперечный) — базовая величина по которой высчитывается ширина или высота внутренних элементов, если размер указан не точно (указан в процентах или не указан вообще, а элемент должен растянуться или сжаться).
Для включения flexbox, любому HTML элементу достаточно присвоить css свойство display:flex; или display:inline-flex;.
<style> .flex{ display: flex; } </style> <div class="flex"> <div class="item">1</div> <div class="item">2</div> </div>
После включения flex свойства, внутри контейнера создаются две оси: главная и поперечная (перпендикулярная (⊥), кросс ось). Все вложенные элементы (первого уровня) выстраиваются по главной оси. По умолчанию главная ось горизонтальная и имеет направление слева направо (→), а кросс ось соответственно вертикальная и направлена сверху вниз (↓).
Главную и кросс оси можно поменять местами, тогда элементы будут располагаться сверху вниз (↓) и когда перестанут вмещаться в высоту то будут двигаться слева направо (→) — то есть оси просто поменялись местами. При этом начало и конец расположения элементов не меняется — меняются только направления (оси)! Именно поэтому нужно представлять себе оси внутри контейнера. Однако не нужно думать, что есть какие-то там «физические» оси и они на что-то влияют. Ось тут — это только лишь направление движения элементов внутри контейнера. Например, если мы указали выравнивание элементов по центру основной оси и потом изменили направление этой основной оси, то изменится и выравнивание: элементы были в середине по горизонтали, а стали в середине по вертикали… См. пример.
Еще одной важной особенностью Флекс-бокс является наличие рядов в поперечном направлении. Чтобы понять о чем речь, давайте представим что есть главная горизонтальная ось, много элементов и они не «лезут» в контейнер, поэтому переходят на другой ряд. Т.е. контейнер выглядит так: контейнер, внутри него два ряда, в каждом ряду по несколько элементов. Представили? А теперь запомните, что выравнивать по вертикали мы можем не только элементы, но и ряды! Как это работает хорошо видно в примере к свойству align-content. А вот так это выглядит схематически:
CSS свойства, которые могут влиять на модель построения макета: float, clear, vertical-align, columns не работают во flex конструкции. Тут используется другая модель построения макета и эти css свойства просто игнорируются.
CSS свойства Flexbox
Flexbox содержит разные css правила для управления всей flex конструкцией. Одни нужно применять к основному контейнеру, а другие к элементам этого контейнера.
Для контейнера
- display:
-
Включает flex свойство для элемента. Под это свойство попадает сам элемент и вложенные в него элементы: затрагиваются только потомки первого уровня — они станут элементами flex контейнера.
- flex — элемент растягивается на всю ширину и имеет свое полное пространство среди окружающих блоков. Происходит перенос строк в начале и в конце блока.
- inline-flex — элемент обтекается другими элементами. При этом его внутренняя часть форматируется как блочный элемент, а сам элемент — как встроенный.
flex и inline-flex отличаются тем что по-разному взаимодействуют с окружающими элементами, подобно display:block и display:inline-block.
- flex-direction:
-
Изменяет направление главной оси контейнера. Поперечная ось меняется соответственно.
- row (default) — направление элементов слева направо (→)
- column — направление элементов сверху вниз (↓)
- row-reverse — направление элементов справа налево (←)
- column-reverse — направление элементов снизу вверх (↑)
Нужно понимать, что при переходе с row на column или с row-reverse на column-reverse меняется только направление осей и больше ничего. Начало и конец расположения блоков остается неизменным (см. картинку в начале). Т.е. если при row элементы начинали свой путь справа/сверху, то при column все останется также — изменится только направление… (см. пример свойства flex-wrap)
- flex-wrap:
-
Управляет переносом непомещающихся в контейнер элементов.
- nowrap (default) — вложенные элементы располагаются в один ряд (при direction=row) или в одну колонку (при direction=column) независимо от того помещаются они в контейнер или нет.
- wrap — включает перенос элементов на следующий ряд, если они не помещаются в контейнер. Так включается движение элементов по поперечной оси.
- wrap-reverse — тоже что wrap только перенос будет не вниз, а вверх (в обратном направлении).
- flex-flow: direction wrap
-
Объединяет оба свойства flex-direction и flex-wrap. Они часто используются вместе, поэтому чтобы писать меньше кода было создано свойство flex-flow.
flex-flow принимает значения двух этих свойств, разделенные пробелом. Или можно указать одно значение любого свойства.
/* только 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-direction и flex-wrap */ flex-flow: row nowrap; flex-flow: column wrap; flex-flow: column-reverse wrap-reverse;
- justify-content:
-
Выравнивает элементы по основной оси: если direction=row, то по горизонтали, а если direction=column, то по вертикали.
- flex-start (default) — элементы будут идти с начала (в конце может остаться место).
- flex-end — элементы выравниваются по концу (место останется в начале)
- center — по центру (место останется слева и права)
- space-between — крайние элементы прижимаются к краям (место между элементами распределяется равномерно)
- space-around — свободное пространство равномерно распределяется между элементами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
- space-evenly — тоже что space-around, только расстояние у крайних элементов до краев контейнера такое же как и между элементами.
- align-content:
-
Выравнивает ряды, в которых находятся элементы по поперечной оси. То же что justify-content только для противоположной оси.
Заметка: Работает только когда высота контейнера фиксированная (выше чем ряды внутри него).
Т.е. если flex-direction: row, то это свойство будет выравнивать невидимые ряды по вертикали
¦
. Тут важно заметить, что высота блока должна быть задана жестко и должна быть больше высоты рядов иначе сами ряды будут растягивать контейнер и любое их выравнивание теряет смысл, потому что между ними нет свободного места… А вот когда flex-direction: column, то ряды движется по горизонтали→
и ширина контейнера почти всегда больше ширины рядов и выравнивание рядов сразу приобретает смысл…Это свойство мало где нужно и вместо него чаще используется align-items (см.ниже).
- stretch (default) — ряды растягиваются заполняя строку полностью
- flex-start — ряды группируются в верхней части контейнера (в конце может остаться место).
- flex-end — ряды группируются в нижней части контейнера (место останется в начале)
- center — ряды группируются по центру контейнера (место останется по краям)
- space-between — крайние ряды прижимаются к краям (место между рядами распределяется равномерно)
- space-around — свободное пространство равномерно распределяется между рядами (крайние элементы не прижимаются к краям). Пространство между краем контейнера и крайними элементами будет в два раза меньше чем пространство между элементами в середине ряда.
- space-evenly — тоже что space-around, только расстояние у крайних элементов до краев контейнера такое же как и между элементами.
- align-items:
-
Выравнивает элементы по поперечной оси внутри ряда (невидимой строки). Т.е. сами ряды выравниваются через align-content, а элементы внутри этих рядов (строк) через align-items и все это по поперечной оси. По главной оси такого разделения нет, там нет понятия рядов и элементы выравниваются через justify-content.
- stretch (default) — элементы растягиваются заполняя строку полностью
- flex-start — элементы прижимаются к началу ряда
- flex-end — элементы прижимаются к концу ряда
- center — элементы выравниваются по центру ряда
- baseline — элементы выравниваются по базовой линии текста
- column-gap:
- gap:
-
Задает размер промежутка между элементами контейнера. Соответственно:
column-gap:
— раздвигает только колонки.gap:
— раздвигает и колонки и ряды.
Размеры можно указать в абсолютных или относительных величинах:
px, em, ...
или в%
.Поддержка
gap
{percent} ( уcolumn-gap
поддержка точно такая же ):
Для элементов контейнера
- flex-grow:
-
Задает коэффициент увеличения элемента при наличии свободного места в контейнере. По умолчанию flex-grow: 0 т.е. никакой из элементов не должен увеличиваться и заполнять свободное место в контейнере.
По умолчанию flex-grow: 0
Примеры:
- Если всем элементам указать flex-grow:1, то все они растянуться одинаково и заполнять все свободное место в контейнере.
- Если одному из элементов указать flex-grow:1, то он заполнит все свободное место в контейнере и выравнивания через justify-content работать уже не будут: свободного места нет выравнивать нечего…
- При flex-grow:1. Если один из них имеет flex-grow:2, то он будет в 2 раза больше, чем все остальные
- Если все flex-блоки внутри flex-контейнера имеют flex-grow:3, то они будут одинакового размера
- При flex-grow:3. Если один из них имеет flex-grow:12, то он будет в 4 раза больше, чем все остальные
Как это работает? Допустим, что контейнер имеет ширину 500px и содержит два элемента, каждый из которых имеет базовую ширину 100px. Значит в контейнере остается 300 свободных пикселей. Теперь, если первому элементу укажем flex-grow:2;, а второму flex-grow: 1;, то блоки займут всю доступную ширину контейнера и ширина первого блока будет 300px, а второго 200px. Объясняется это тем, что доступные 300px свободного места в контейнере распределились между элементами в соотношении 2:1, +200px первому и +100px второму.
Заметка: в значении можно указывать дробные числа, например: 0.5 — flex-grow:0.5
- flex-shrink:
-
Задает коэффициент уменьшения элемента. Свойство противоположное flex-grow и определяет как элемент должен сжиматься, если в контейнере не остается свободного места. Т.е. свойство начинает работать, когда сумма размеров всех элементов больше чем размер контейнера.
По умолчанию flex-shrink:1
Допустим, что контейнер имеет ширину 600px и содержит два элемента, каждый из которых имеет ширину 300px — flex-basis:300px;. Т.е. два элемента полностью заполняют контейнер. Первому элементу укажем flex-shrink: 2;, а второму flex-shrink: 1;. Теперь уменьшим ширину контейнера на 300px, т.е. элементы должны сжаться на 300px чтобы находится внутри контейнера. Сжиматься они будут в соотношении 2:1, т.е. первый блок сожмется на 200px, а второй на 100px и новые размеры элементов станут 100px и 200px.
Заметка: в значении можно указывать дробные числа, например: 0.5 — flex-shrink:0.5
- flex-basis:
-
Устанавливает базовую ширину элемента — ширину до того как будут высчитаны остальные условия влияющие на ширину элемента. Значение можно указать в
px, em, rem, %, vw, vh
и т.д. Итоговая ширина будет зависеть от базовой ширины и значений flex-grow, flex-shrink и контента внутри блока. Приauto
элемент получает базовую ширину относительно контента внутри него.По умолчанию: auto
Иногда лучше установить ширину элемента жестко через привычное свойство width. Например, width: 50%; будет означать, что элемент внутри контейнера будет ровно 50%, однако при этом все также будут работать свойства flex-grow и flex-shrink. Такое может быть нужно, когда элемент растягивается контентом внутри него, больше указанного во flex-basis. Пример смотрите в заметках.
flex-basis будет «жестким», если обнулить растяжение и сжатие: flex-basis:200px; flex-grow:0; flex-shrink:0;. Все это можно записать так
flex:0 0 200px;
. - flex: {grow shrink basis}
-
Короткая запись трех свойств:
flex-grow flex-shrink flex-basis
.По умолчанию: flex: 0 1 auto
Однако можно указать и одно, и два значения:
flex: none; /* 0 0 auto */ /* число */ flex: 2; /* flex-grow (flex-basis переходит в 0) */ /* не число */ flex: 10em; /* flex-basis: 10em */ flex: 30px; /* flex-basis: 30px */ flex: auto; /* flex-basis: auto */ flex: content; /* flex-basis: content */ flex: 1 30px; /* flex-grow и flex-basis */ flex: 2 2; /* flex-grow и flex-shrink (flex-basis переходит в 0) */ flex: 2 2 10%; /* flex-grow и flex-shrink и flex-basis */
- align-self:
-
Позволяет изменить свойство align-items, только для отдельного элемента.
По умолчанию: от align-items контейнера
- stretch — элемент растягиваются заполняя строку полностью
- flex-start — элемент прижимаются к началу строки
- flex-end — элемент прижимаются к концу строки
- center — элемент выравниваются по центру строки
-
baseline — элемент выравниваются по базовой линии текста
- order:
-
Позволяет менять порядок (позицию, положение) элемента в общем ряду.
По умолчанию: order: 0
По умолчанию элементы имеют order: 0 и ставятся в порядке их появления в HTML коде и направления ряда. Но если изменить значение свойства order, то элементы будут выстраиваться в порядке значений: -1 0 1 2 3 …. Например если одному из элементов указать order: 1, то сначала будут идти все нулевые, а потом элемент с 1.
Так можно, например, первый элемент перекинуть в конец, при этом не меняя направление движения остальных элементов или HTML код.
Заметки
Чем отличается flex-basis от width?
Ниже важные различия между flex-basis и width / height:
-
flex-basis работает только для главной оси. Это значит что при flex-direction:row flex-basis контролирует ширину (width), а при flex-direction:column контролирует высоту (height). Смотрите пример.
-
flex-basis применяется только к flex элементам. А значит если отключить flex у контейнера это свойство не будет иметь эффекта.
-
Абсолютные элементы контейнера не участвуют во flex конструкции… А значит, flex-basis не влияет на элементы flex контейнера, если они абсолютны position:absolute. Им нужно будет указать width / height.
- При использовании css свойства
flex
три значения: flex-grow / flex-shrink / flex-basis можно скомбинировать и записать коротко —flex:0 0 50%
. Тогда как при использовании width, grow и shrink придется писать отдельно. Например: flex:0 0 50% == width:50%; flex-shrink:0;. Иногда это просто неудобно.
По возможности все же отдавайте предпочтение flex-basis. Используйте width только когда не подходит flex-basis.
Отличие flex-basis от width — баг или фича?
Контент внутри flex элемента распирает его и не может выйти за его пределы. Однако если установить ширину через width или max-width, а не flex-basis, то элемент внутри flex контейнера сумеет выйти за пределы этого контейнера (иногда нужно именно такое поведение). Пример:
Примеры Flex верстки
В примерах нигде не используются префиксы для кроссбраузерности. Сделал я так для удобного чтения css. Поэтому примеры смотрите в последних версиях Chrome или Firefox.
#1 Простой пример с выравниванием по вертикали и горизонтали
Начнем с самого простого примера — выравнивание по вертикали и горизонтали одновременно и при любой высоте блока, даже резиновой.
<div class="parent"> <span class="child">Текст по середине</span> </div> <style> .parent { display: flex; } .child { margin: auto; } </style>
Или так, без блока внутри:
<div class="center-text"> Текст по середине </div> <style> .center-text { display: flex; justify-content: center; align-items: center; } </style>
#1.2 Разделение (разрыв) между элементами флекс блока
Чтобы расположить элементы контейнера по краям и произвольно выбрать элемент после которого будет разрыв, нужно использовать свойство margin-left:auto
или margin-right:auto
.
#2 Адаптивное меню на flex
Сделаем меню в самом верху страницы. На широком экране оно должно быть справа. На среднем выравниваться по середине. А на маленьком каждый элемент должен быть на новой строке.
<div class="nav"> <a href="#">Главная</a> <a href="#">О нас</a> <a href="#">Продукты</a> <a href="#">Контакты</a> </div> <style> .nav { display: flex; justify-content: flex-end; /* разместим справа */ background: #6e9cc3; } .nav a { color:#fff; padding:15px 10px; text-decoration:none; text-align:center; } .nav a:hover { background:#5c8db7; } /* меньше 800px */ @media all and (max-width: 800px) { .nav { justify-content: space-around; } .nav a{ flex-grow:1; /* растягиваться на всю ширину */ } } /* меньше 500px */ @media all and (max-width: 500px) { .nav { flex-direction: column; } } </style>
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#3 Адаптивные 3 колонки
Этот пример показывает как быстро и удобно сделать 3 колонки, которые при сужении будут превращаться в 2 и затем в 1.
Обратите внимание, что сделать это можно без использования media правил, все на flex.
<div class="flex"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> </div> <style> .flex{ display: flex; flex-wrap: wrap; max-width: 700px; /* макс ширина */ margin: 0 auto; /* выровняем по центру */ } .item{ flex:1 1 calc(33.33% - 30px); /* отнимем margin и скажем растягиваться */ margin:5px; box-sizing:border-box; /* чтобы внутренний отступ не влиял когда там будет текст... */ min-width:170px; /* мин. ширина блока, чтобы переносились на другой ряд */ padding:50px 20px; font-size:400%; text-align:center; background:#b5ced8; /* для красоты */ } </style>
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#4 Адаптивные блоки на flex
Допустим нам нужно вывести 3 блока, один большой и два маленьких. При этом нужно чтобы блоки подстраивались под маленькие экраны. Делаем:
<div class="flex"> <div class="mainitem">1</div> <div class="sideitem"> <div class="item">2</div> <div class="item">3</div> </div> </div> <style> .flex{ display: flex; max-width: 700px; /* макс ширина блока */ margin: 0 auto; /* выравниваем блок по центру */ font-size:400%; } .mainitem, .item{ flex-grow:1; /* растягивание элементов */ background:#b5ced8; display: flex; justify-content: center; align-items: center; /* цифры по центру */ } .mainitem{ min-height:300px; /* высота основного блока */ } .sideitem{ /* flex:0 0 150px; */ flex-basis:150px; /* ширина 150 */ flex-shrink:0; /* Убираем уменьшение = 150 */ display: flex; flex-direction: column; } .item{ flex-basis:50%; min-height:150px; margin-left:10px; } .item:first-child{ margin-bottom:10px; } /* меньше 600px */ @media screen and (max-width: 600px) { .flex{ flex-wrap: wrap; } /* для переноса */ .sideitem{ flex-direction:row; flex-basis:100%; } .item{ margin-left:0; margin-top:10px; } .item:first-child{ margin-bottom:0; margin-right:10px; } } /* меньше 450px */ @media screen and (max-width: 450px) { .sideitem{ flex-wrap: wrap; } /* разрешаем перенос */ .item{ flex-basis:100%; } /* на всю ширину */ .item:first-child{ margin-right:0; } } </style>
Перейдите в jsfiddle.net и изменяйте ширину секции «результат»
#5 Галерея на flex и transition
Этот пример показывает как быстро можно сделать симпатичный аккордеон с картинками на flex. Обратите внимание на свойство transition для flex.
<div class="flex"> <div class="item img1"></div> <div class="item img2"></div> <div class="item img3"></div> <div class="item img4"></div> <div class="item img5"></div> </div> <style> .flex { display: flex; overflow:hidden; /*скроем тень*/ } .item { height:300px; flex:20%; /* = flex-basis:20%; */ transition: flex 300ms ease; box-shadow: 0 0 19px 3px #000; margin: 1px; /* красивости тени */ } .item:hover { flex: 0.1 0.1 400px; background-size: 100% 100% } .img1 { background: url('http://lorempixel.com/400/300/cats/1') 0 0 no-repeat; } .img2 { background: url('http://lorempixel.com/400/300/cats/2') 0 0 no-repeat; } .img3 { background: url('http://lorempixel.com/400/300/cats/3') 0 0 no-repeat; } .img4 { background: url('http://lorempixel.com/400/300/cats/4') 0 0 no-repeat; } .img5 { background: url('http://lorempixel.com/400/300/cats/5') 0 0 no-repeat; } </style>
#6 Флекс во флекс (просто пример)
Задача сделать гибкий блок. Так чтобы начало текста в каждом блоке находилось на одной линии по горизонтали. Т.е. при сужении ширины, блоки растут в высоту. Нужно, чтобы картинка была вверху, кнопка всегда внизу, а текст по середине начинался по одной горизонтальной линии…
Для решения этой задачи, сами блоки растягиваются флексом и им установлена максимально возможная ширина. Каждый внутренний блок также является флекс конструкцией, с повернутой осью flex-direction:column; и элемент в середине (где находится текст) растягивается flex-grow:1; чтобы заполнить всё свободное пространство, так достигается результат — текст начинался с одной линии…
Еще примеры
Смотрите здесь alexriz.github.io
Поддержка браузерами — 99%
Полной поддержки разумеется нет, однако все современные браузеры поддерживают flexbox конструкции. Для некоторых все еще нужно указывать префиксы.
Чтобы знать какие префиксы актуальны на сегодня (июнь. 2019), приведу пример всех flex правил с нужными префиксами:
/* Контейнер */ .flex { display:-ms-flexbox; display:flex; display:-ms-inline-flexbox; display:inline-flex; -ms-flex-direction:column; flex-direction:column; -ms-flex-wrap:wrap; flex-wrap:wrap; -ms-flex-flow:column wrap; flex-flow:column wrap; -ms-flex-pack:justify; justify-content:space-between; -ms-flex-line-pack:distribute; align-content:space-around; } /* Элементы */ .flex-item { -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:2; flex-shrink:2; -ms-flex-preferred-size:100px; flex-basis:100px; -ms-flex:1 2 100px; flex:1 2 100px; -ms-flex-item-align:center; align-self:center; -ms-flex-order:2; order:2; }
Лучше если свойства с префиксами будут идти до оригинального свойства.
В этом списке нет ненужных на сегодня (по caniuse) префиксов, но вообще префиксов больше.
Видео
Ну и не забывайте про видео, там порой тоже интересно и понятно. Вот парочка популярных:
Полезные ссылки по Flex
-
flexboxfroggy.com — игра обучающая flexbox.
-
Flexplorer — наглядный конструктор flex кода.
- Шпаргалка Flexbox
—
Использовал при написании:
- https://habrahabr.ru/post/242545/
- http://html5.by/blog/flexbox/
- https://css-tricks.com/snippets/css/a-guide-to-flexbox/
- https://www.w3.org/TR/css-flexbox-1/
Полное руководство по Flexbox
Модуль Flexbox-лейаута (flexible box — «гибкий блок», на данный момент W3C
Candidate Recommendation) ставит задачу предложить более эффективный способ
вёрстки, выравнивания и распределения свободного места между элементами в
контейнере, даже когда их размер неизвестен и/или динамический (отсюда слово
«гибкий»).
Главная задумка flex-вёрстки в наделении контейнера способностью изменять
ширину/высоту (и порядок) своих элементов для наилучшего заполнения
пространства (в большинстве случаев — для поддержки всех видов дисплеев и
размеров экранов). Flex-контейнер растягивает элементы для заполнения
свободного места или сжимает их, чтобы предотвратить выход за границы.
Самое важное, flexbox-лейаут не зависит от направления в отличие от обычных
лейаутов (блоки, располагающиеся вертикально, и инлайн-элементы,
располагающиеся горизонтально). В то время, как обычный лейаут отлично
подходит для веб-страниц, ему не хватает гибкости (никакого каламбура) для
поддержки больших или сложных приложений (особенно когда дело доходит до
смены ориентации экрана, изменения размера, растягивания, сжатия и т.п.).
Замечание: Flexbox-лейаут лучше всего подходит для составных частей
приложения и мелкомасштабных лейаутов, в то время как Grid-лейаут больше
используется для лейаутов большого масштаба.
Основы
Т.к. flexbox — это целый модуль, а не просто единичное свойство, он
объединяет в себе множество свойств. Некоторые из них должны применяться к
контейнеру (родительскому элементу, так называемому flex-контейнеру), в то
время как другие свойства применяются к дочерним элементам, или
flex-элементам.
Если обычный лейаут основывается на направлениях потоков блочных и
инлайн-элементов, то flex-лейаут основывается на «направлениях flex-потока».
Ознакомьтесь с этой схемой из спецификации, разъясняющей основную идею
flex-лейаутов.
В основном элементы будут распределяться либо вдоль главной оси
(от main-start до main-end), либо вдоль поперечной оси
(от cross-start до cross-end).
- main-axis — главная ось, вдоль которой располагаются flex-элементы.
Обратите внимание, она необязательно должна быть горизонтальной, всё зависит
от свойстваflex-direction
(см. ниже). - main-start | main-end — flex-элементы размещаются в контейнере от
позиции main-start до позиции main-end. - main size — ширина или высота flex-элемента в зависимости от выбранной
основной величины. Основная величина может быть либо шириной, либо высотой
элемента. - cross axis — поперечная ось, перпендикулярная к главной. Её направление
зависит от направления главной оси. - cross-start | cross-end — flex-строки заполняются элементами и
размещаются в контейнере от позицииcross-start
и до позицииcross-end
. - cross size — ширина или высота flex-элемента в зависимости от выбранной
размерности равняется этой величине. Это свойство совпадает сwidth
или
height
элемента в зависимости от выбранной размерности.
Свойства
display: flex | inline-flex;
Применяется к: родительскому элементу flex-контейнера.
Определяет flex-контейнер (инлайновый или блочный в зависимости от выбранного
значения), подключает flex-контекст для всех его непосредственных потомков.
display: other values | flex | inline-flex;
Имейте в виду:
- CSS-столбцы
columns
не работают с flex-контейнером float
,clear
иvertical-align
не работают с flex-элементами
flex-direction
Применяется к: родительскому элементу flex-контейнера.
Устанавливает главную ось main-axis
, определяя тем самым направление для
flex-элементов, размещаемых в контейнере.
flex-direction: row | row-reverse | column | column-reverse
row
(по умолчанию): слева направо дляltr
, справа налево дляrtl
;row-reverse
: справа налево дляltr
, слева направо дляrtl
;column
: аналогичноrow
, сверху вниз;column-reverse
: аналогичноrow-reverse
, снизу вверх.
flex-wrap
Применяется к: родительскому элементу flex-контейнера.
Определяет, будет ли контейнер однострочным или многострочным, а также
направление поперечной оси, определяющей направление, в котором будут
располагаться новые строки.
flex-wrap: nowrap | wrap | wrap-reverse
nowrap
(по умолчанию): однострочный / слева направо дляltr
, справа
налево дляrtl
;wrap
: многострочный / слева направо дляltr
, справа налево дляrtl
;wrap-reverse
: многострочный / справа налево дляltr
, слева направо
дляrtl
.
flex-flow
Применяется к: родительскому элементу flex-контейнера.
Это сокращение для свойств flex-direction
и flex-wrap
, вместе
определяющих главную и поперечную оси. По умолчанию принимает
значение row nowrap
.
flex-flow: <'flex-direction'> || <'flex-wrap'>
justify-content
Применяется к: родительскому элементу flex-контейнера.
Определяет выравнивание относительно главной оси. Помогает распределить
оставшееся свободное место в случае, когда элементы строки не «тянутся»,
либо тянутся, но уже достигли своего максимального размера. Также позволяет в
некотором роде управлять выравниванием элементов при выходе за границы строки.
justify-content: flex-start | flex-end | center | space-between | space-around
flex-start
(по умолчанию): элементы сдвигаются к началу строки;flex-end
: элементы сдвигаются к концу строки;center
: элементы выравниваются по центру строки;space-between
: элементы распределяются равномерно (первый элемент в
начале строки, последний — в конце);space-around
: элементы распределяются равномерно с равным расстоянием
между собой и границами строки.
align-items
Применяется к: родительскому элементу flex-контейнера.
Определяет поведение по умолчанию для того, как flex-элементы располагаются
относительно поперечной оси на текущей строке. Считайте это
версией justify-content
для поперечной оси (перпендикулярной к основной).
align-items: flex-start | flex-end | center | baseline | stretch
flex-start
: границаcross-start
для элементов располагается на
позицииcross-start
;flex-end
: границаcross-end
для элементов располагается на
позицииcross-end
;center
: элементы выравниваются по центру поперечной оси;baseline
: элементы выравниваются по своей базовой линии;stretch
(по умолчанию): элементы растягиваются, заполняя контейнер
(с учётомmin-width
/max-width
).
align-content
Применяется к: родительскому элементу flex-контейнера.
Выравнивает строки flex-контейнера при наличии свободного места на поперечной
оси аналогично тому, как это делает justify-content
на главной оси.
Замечание: это свойство не работает с однострочным flexbox.
align-content: flex-start | flex-end | center | space-between | space-around | stretch
flex-start
: строки выравниваются относительно начала контейнера;flex-end
: строки выравниваются относительно конца контейнера;center
: строки выравниваются по центру контейнера;space-between
: строки распределяются равномерно (первая строка в начале
строки, последняя — в конце);space-around
: строки распределяются равномерно с равным расстоянием
между собой;stretch
(по умолчанию): строки растягиваются, заполняя свободное
пространство.
order
Применяется к: дочернему элементу / flex-элементу.
По умолчанию flex-элементы располагаются в исходном порядке. Тем не менее,
свойство order
может управлять порядком их расположения в контейнере.
flex-grow
Применяется к: дочернему элементу / flex-элементу.
Определяет для flex-элемента возможность «вырастать» при необходимости.
Принимает безразмерное значение, служащее в качестве пропорции. Оно
определяет, какую долю свободного места внутри контейнера элемент может занять.
Если у всех элементов свойство flex-grow
задано как 1
, то каждый потомок
получит внутри контейнера одинаковый размер. Если вы задали одному из
потомков значение 2
, то он заберёт в два раза больше места, чем другие.
flex-grow: <number> (по умолчанию 0)
Отрицательные числа не принимаются.
flex-shrink
Применяется к: дочернему элементу / flex-элементу.
Определяет для flex-элемента возможность сжиматься при необходимости.
flex-shrink: <number> (default 1)
Отрицательные числа не принимаются.
flex-basis
Применяется к: дочернему элементу / flex-элементу.
Определяет размер по умолчанию для элемента перед распределением пространства
в контейнере.
flex-basis: <length> | auto (default auto)
flex
Применяется к: дочернему элементу / flex-элементу.
Это сокращение для flex-grow
, flex-shrink
и flex-basis
. Второй и третий
параметры (flex-shrink
, flex-basis
) необязательны.
Значение по умолчанию — 0 1 auto
.
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
align-self
Применяется к: дочернему элементу / flex-элементу.
Позволяет переопределить выравнивание, заданное по умолчанию или
в align-items
, для отдельных flex-элементов.
Обратитесь к описанию свойства align-items
для лучшего понимания доступных
значений.
align-self: auto | flex-start | flex-end | center | baseline | stretch
Примеры
Начнём с очень-очень простого примера, встречающегося практически каждый день:
выравнивание точно по центру. Нет ничего проще, если использовать flexbox.
.parent {
display: flex;
height: 300px; /* Или что угодно */
}
.child {
width: 100px; /* Или что угодно */
height: 100px; /* Или что угодно */
margin: auto; /* Магия! */
}
Этот пример основывается на том, что margin
во flex-контейнере, заданный
как auto
, поглощает лишнее пространство, поэтому задание отступа таким
образом выровняет элемент ровно по центру по обеим осям.
Теперь давайте используем какие-нибудь свойства. Представьте набор из 6
элементов фиксированного размера (для красоты), но с возможностью изменения
размера контейнера. Мы хотим равномерно распределить их по горизонтали, чтобы
при изменении размера окна браузера всё выглядело хорошо (без @media
-запросов!).
.flex-container {
/* Сначала создадим flex-контекст */
display: flex;
/* Теперь определим направление потока и хотим ли мы, чтобы элементы
переносились на новую строку
* Помните, что это тоже самое, что и:
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
/* Теперь определим, как будет распределяться пространство */
justify-content: space-around;
}
Готово. Всё остальное — уже дело оформления. Ниже размещён CodePen,
демонстрирующий этот пример. Обязательно попробуйте растянуть/сжать окно
браузера и посмотрите, что произойдёт.
Check out this Pen!
<script async src=»http://codepen.io/assets/embed/ei.js»></script>
Давайте попробуем что-нибудь ещё. Представьте, что нам нужна выровненная по
правому краю навигация в самом верху нашего сайта, но мы хотим, чтобы она
выравнивалась по центру для экранов среднего размера и превращалась в один
столбец на маленьких. Всё достаточно просто.
/* Большие экраны */
.navigation {
display: flex;
flex-flow: row wrap;
/* Сдвигает элементы к концу строки по главной оси */
justify-content: flex-end;
}
/* Экраны среднего размера */
@media all and (max-width: 800px) {
.navigation {
/* Для экранов среднего размера мы выравниваем навигацию по центру,
равномерно распределяя свободное место между элементами */
justify-content: space-around;
}
}
/* Маленькие экраны */
@media all and (max-width: 500px) {
.navigation {
/* На маленьких экранах вместо строки мы располагаем элементы в столбце */
flex-direction: column;
}
}
Check out this Pen!
<script async src=»http://codepen.io/assets/embed/ei.js»></script>
Давайте попробуем кое-что получше и поиграем с гибкостью flex-элементов! Как
насчёт ориентированного на мобильные устройства трёхколоночного макета с
полноширинной шапкой и подвалом? И другим порядком расположения.
.wrapper {
display: flex;
flex-flow: row wrap;
}
/* Задаём всем элементам ширину в 100% */
.header, .main, .nav, .aside, .footer {
flex: 1 100%;
}
/* В этом случае мы полагаемся на исходный порядок для ориентации на
* мобильные устройства:
* 1. header
* 2. nav
* 3. main
* 4. aside
* 5. footer
*/
/* Экраны среднего размера */
@media all and (min-width: 600px) {
/* Оба сайдбара располагаются в одной строке */
.aside { flex: 1 auto; }
}
/* Большие экраны */
@media all and (min-width: 800px) {
/* Мы меняем местами элементы .aside-1 и .main, а также сообщаем
* элементу .main забирать в два раза больше места, чем сайдбары.
*/
.main { flex: 2 0px; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
Check out this Pen!
<script async src=»http://codepen.io/assets/embed/ei.js»></script>
Похожие свойства
- Grid
Другие ресурсы
- Flexbox in the CSS specifications
- Flexbox at MDN
- Flexbox at Opera
- Diving into Flexbox by Bocoup
- Mixing syntaxes for best browser support on CSS-Tricks
- Flexbox by Raphael Goetter (FR)
- Flexplorer by Bennett Feely
Поддержка браузерами
(modern)
означает поддержку нового синтаксиса из спецификации (display: flex;
)(hybrid)
означает поддержку старого неофициального синтаксиса из 2011 (display: flexbox;
)(old)
означает поддержку старого синтаксиса из 2009 (display: box;
)
Chrome | Safari | Firefox | Opera | IE | Android | iOS |
---|---|---|---|---|---|---|
21+ (modern) 20- (old) |
3.1+ (old) | 2-21 (old) 22+ (new) |
12.1+ (modern) | 10+ (hybrid) | 2.1+ (old) | 3.2+ (old) |
Браузер Blackberry версии 10+ поддерживает новый синтаксис.
Для более подробной информации о том, как и когда использовать различные
синтаксисы для обеспечения лучшей поддержки браузерами, обратитесь
к этой статье (CSS-Tricks) или этой статье (DevOpera).
SASS-@mixin
для облегчения боли:
@mixin flexbox() {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin flex($values) {
-webkit-box-flex: $values;
-moz-box-flex: $values;
-webkit-flex: $values;
-ms-flex: $values;
flex: $values;
}
@mixin order($val) {
-webkit-box-ordinal-group: $val;
-moz-box-ordinal-group: $val;
-ms-flex-order: $val;
-webkit-order: $val;
order: $val;
}
.wrapper {
@include flexbox();
}
.item {
@include flex(1 200px);
@include order(2);
}