Flex контейнер: Что происходит при создании контейнера Flexbox? / Habr – Свойства flex-контейнера | WebReference

Содержание

Свойства flex-контейнера | WebReference

flex-direction

Это свойство указывает, как flex-элементы располагаются во flex-контейнере, задавая направление главной оси flex-контейнера. Элементы могут располагаться по двум основным направлениям — как строки по горизонтали или как столбцы по вертикали.

Значения

Со значением row flex-элементы располагаются в ряд слева направо в контексте ltr.

.flex-container {
  flex-direction: row;
}

При значении row-reverse flex-элементы располагаются в ряд справа налево в контексте ltr.

.flex-container {
  flex-direction: row-reverse;
}

Со значением column flex-элементы располагаются в колонку сверху вниз.

.flex-container {
  flex-direction: column;
}

При значении column-reverse flex-элементы располагаются в колонку снизу вверх.

Значение по умолчанию: row.

row и row-reverse зависят от режима написания, так что в контексте rtl они будут соответственно перевёрнуты.

flex-wrap

Исходная концепция flexbox — это контейнер для установки своих элементов в одну строку. Если flex-контейнер располагает свои элементы в одну или несколько строк, то свойство flex-wrap управляет направлением, в котором эти новые строки располагаются.

Значения
.flex-container {
  flex-wrap: nowrap;
}

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

.flex-container {
  flex-wrap: wrap;
}

flex-элементы отображаются в несколько строк, если это необходимо, слева направо и сверху вниз.

.flex-container {
  flex-wrap: wrap-reverse;
}

flex-элементы отображаются в несколько строк, если это необходимо, слева направо и снизу вверх.

Значение по умолчанию: nowrap.

Эти свойства зависят от режима написания, поэтому в контексте rtl они будут соответственно перевёрнуты.

flex-flow

Это свойство является сокращением для установки свойств flex-direction и flex-wrap.

Значения
.flex-container {
  flex-flow: <flex-direction> || <flex-wrap>;
}

Значение по умолчанию: row nowrap.

justify-content

Свойство justify-content выравнивает flex-элементы вдоль главной оси текущей строки flex-контейнера. Свойство помогает распределять оставшееся свободное пространство, когда все flex-элементы в строке не растягиваются или растягиваются, но достигли максимального размера.

Значения
.flex-container {
  justify-content: flex-start;
}

flex-элементы выравниваются по левой стороне flex-контейнера в контексте ltr.

.flex-container {
  justify-content: flex-end;
}

flex-элементы выравниваются по правой стороне flex-контейнера в контексте ltr.

.flex-container {
  justify-content: center;
}

flex-элементы выравниваются по центру flex-контейнера.

.flex-container {
  justify-content: space-between;
}

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

.flex-container {
  justify-content: space-around;
}

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

Значение по умолчанию: flex-start.

align-items

flex-элементы могут быть выровнены по поперечной оси текущей строки flex-контейнера, подобно justify-content, но в перпендикулярном направлении. Это свойство устанавливает выравнивание по умолчанию для всех flex-элементов, включая анонимных.

Значения
.flex-container {
  align-items: stretch;
}

flex-элементы заполняют всю высоту (или ширину) от поперечного начала до поперечного конца flex-контейнера.

.flex-container {
  align-items: flex-start;
}

flex-элементы располагаются у поперечного начала flex-контейнера.

.flex-container {
  align-items: flex-end;
}

flex-элементы располагаются у поперечного конца flex-контейнера.

.flex-container {
  align-items: center;
}

flex-элементы располагаются в центре поперечной оси flex-контейнера.

.flex-container {
  align-items: baseline;
}

flex-элементы выравниваются таким образом, чтобы их базовые линии были выровнены.

Значение по умолчанию: stretch.

Подробнее о том, как рассчитываются базовые линии, читайте здесь.

align-content

Свойство align-content выравнивает строки внутри flex-контейнера, когда в поперечной оси имеется дополнительное пространство, подобно тому, как justify-content выравнивает отдельные элементы по главной оси.

Значения
.flex-container {
  align-content: stretch;
}

flex-элементы отображаются с дополнительным пространством после каждой строки flex-элементов.

.flex-container {
  align-content: flex-start;
}

flex-элементы располагаются стопкой возле поперечного начала flex-контейнера.

.flex-container {
  align-content: flex-end;
}

flex-элементы располагаются стопкой возле поперечного конца flex-контейнера.

.flex-container {
  align-content: center;
}

Строки flex-элементов располагаются в центре поперечной оси flex-контейнера.

.flex-container { 
  align-content: space-between;
}

Строки flex-элементов отображаются с равным интервалом между ними, первая и последняя строки выравниваются по краям flex-контейнера.

.flex-container {
  align-content: space-around;
}

flex-элементы отображаются с равным интервалом вокруг каждой строки.

Значение по умолчанию: stretch.

Это свойство имеет эффект только тогда, когда flex-контейнер содержит несколько строк flex-элементов. Если элементы располагаются в одну строку, свойство align-content никак не влияет на макет.

Замечания

  • Все свойства column-* не оказывают влияния на flex-контейнер.
  • Псевдоэлементы ::first-line и ::first-letter не применяются к flex-контейнерам.

Автор и редакторы

Автор: Димитар Стоянов

Последнее изменение: 20.02.2019

Редакторы: Влад Мержевич

Курс по вёрстке сайта на CSS Grid

Что происходит, когда вы создаете flex-контейнер? — CAT.IN.WEB

В этой статье мы подробно рассмотрим, что на самом деле происходит при добавлении правила display: flex в таблицу стилей.

Flex-контейнер, пожалуйста!

Чтобы использовать флексбоксы, необходимо сначала создать флекс-контейнер. Для этого используется инструкция display: flex.

Что же на самом деле значит display: flex. В спецификации Display Module Level 3 каждое значение свойства display описывается как комбинация двух моделей поведения: внутренней и внешней. Когда мы устанавливаем display: flex, на самом деле это значит display: block flex. То есть внешний тип отображения контейнера block, и он ведет себя как обычный блочный элемент в нормальном потоке. Внутренний тип отображения – flex, поэтому его прямые потомки придерживаются правил флекс-раскладки.

Можно также определить тип отображения inline-flex, что будет означать display: inline flex, то есть сам элемент будет вести себя как строчный, а внутри ничего не изменится. Дети инлайн-флексового контейнера ведут себя точно так же, как дети блочно-флексового.

Ряды или колонки?

С контейнером определились, теперь поговорим о некоторых стартовых значениях. Если не устанавливать никакие дополнительные свойства, то флекс-элементы выстраиваются в ряд. Это происходит из-за того, что значением по умолчанию для свойства flex-direction является row — ряд.

Свойство flex-direction устанавливает направление главной оси контейнера. Другие значение, которые оно может принимать:

  • column
  • row-reverse
  • column-reverse

Значение row заставляет элементы выстраиваться один за другим (как в html-коде). По сути ряд ведет себя как обычная строка, идущая слева направо. Место начала строки в спецификации называется  main-start:

Если использовать значение column, элементы сформируют колонку, которая идет сверху вниз. Это нормальный поток блоков в документе. Соответственно main-start перемещается наверх.

row-reverse меняет main-start и main-end местами, и элементы выстраиваются в обратном порядке.

Вложенные флекс-контейнеры | WebReference

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

Вроде этого.

<!doctype html>
<title>Пример</title>
<style>
.container { 
  display: flex;
}
.red {
  background: orangered;
  display: flex;
  flex-direction: column;
}
.green {
  background: yellowgreen;
}
.blue {
  background: steelblue;
}
.container div {
  font-size: 5vw;
  padding: .5em;
  color: white;
  flex: 1;
}
</style>
<div>
  <div>1
    <div>1a</div>
    <div>1b</div>
  </div>
  <div>2</div>
  <div>3</div>
</div>

В данном примере мы применяем display: flex одновременно к внешнему контейнеру и к красному флекс-элементу. Но с красным флекс-элементом мы используем flex-direction: column, в результате чего его флекс-элементы располагаются вертикально друг под другом. Значением по умолчанию для flex-direction является row, поэтому мы не стали использовать это свойство для внешнего контейнера — по умолчанию флекс-элементы располагаются в ряд.

Двумерные макеты сайтов

Когда мы разбирали пример макета Святого Грааля, то использовали флексбоксы только для средней части, а шапку и подвал оставили блочными элементами. Мы применяли флексбоксы для размещения трёх флекс-элементов по горизонтали (в ряд), но не задавали флекс-элементы по вертикали (в колонку). Другими словами, у нас был одномерный макет. Несмотря на то, что страница в целом представляла собой двумерный макет, флексбоксы поддерживают макет только в одном из этих измерений.

Мы могли бы изменить тот пример для использования флексбоксов в двух измерениях — по рядам и колонкам. Для этого воспользуемся концепцией, показанной выше. Таким образом, мы можем использовать один флекс-контейнер для вертикальной компоновки, а другой — для горизонтальной.

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

Горизонтальный макет состоит из <nav>, <article> и <aside>. Все они содержатся во втором ряду, но их необходимо разместить горизонтально. Следовательно, мы можем сделать второй ряд флекс-контейнером и заставить его содержимое выстроиться в ряд.

Итак, вот рабочий пример.

<!doctype html>
<title>Пример</title>
<style>
* {
  box-sizing: border-box; 
}
body {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  margin: 0;
}
#main {
  display: flex;
  flex: 1;
}
#main > article {
  flex: 1;
}
#main > nav, 
#main > aside {
  flex: 0 0 20vw;
  background: beige;
}
#main > nav {
  order: -1;
}
header, footer {
  background: yellowgreen;
  height: 20vh;
}
header, footer, article, nav, aside {
  padding: 1em;
}
</style>
<body>
  <header>Шапка</header>
  <div>
    <article>Статья</article>
    <nav>Навигация</nav>
    <aside>Боковая панель</aside>
  </div>
  <footer>Подвал</footer>
</body>

В нашем случае мы использовали следующий код для элемента <body>.

body {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  margin: 0;
}

display: flex делает <body> флекс-контейнером, а flex-direction: column отображает его флекс-элементы в колонку. Мы также задали минимальную высоту для внешнего флекс-контейнера, чтобы макет занимал всю высоту экрана.

А теперь для вложенного флекс-контейнера.

#main {
  display: flex;
  flex: 1;
}

Добавление display: flex делает #main флекс-контейнером, подобно <body>. Теперь его дочерние элементы становятся флекс-элементами. flex: 1 гарантирует, что он будет расти так, чтобы занимать максимум доступного пространства.

Мы могли бы добавить flex-direction: row, чтобы явно указать направление, но в любом случае row является значением по умолчанию.

Остальное — просто стилизация и упорядочивание флекс-элементов во вложенном флекс-контейнере.

#main > article {
  flex: 1;
}
#main > nav, 
#main > aside {
  flex: 0 0 20vw;
  background: beige;
}
#main > nav {
  order: -1;
}

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

Кроме того, я уверен, вы можете придумать множество других применений для вложенных флекс-контейнеров, помимо макетов веб-сайтов.

Вложенные флексбоксы против CSS Grid

Каждый раз, когда используете вложенные флекс-контейнеры, подумайте, не лучше ли вместо этого использовать CSS Grid. Он специально разработан для двумерных макетов, поэтому для создания таких макетов не требуется вложенность (хотя она поддерживается).

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

Автор и редакторы

Автор: Йен Диксон

Последнее изменение: 21.10.2019

Редакторы: Влад Мержевич

Курс по вёрстке сайта на CSS Grid

выравнивание, многострочность — учебник CSS

Давайте познакомимся со свойствами, предназначенными специально для flex-контейнера — элемента, которому задано свойство display со значением flex.

Свойство flex-direction

Свойство flex-direction позволяет управлять направлением главной оси flex-контейнера. Данное свойство предназначено для применения к контейнерам и принимает следующие значения:

  • row (значение по умолчанию) — направление главной оси пролегает слева направо (как на схеме выше) для локали LTR и справа налево для локали RTL.
  • row-reverse — здесь, наоборот, направление главной оси пролегает справа налево, если локаль LTR, и слева направо, если локаль RTL.
  • column — направление главной оси пролегает сверху вниз.
  • column-reverse — направление главной оси пролегает снизу вверх.

Работа этих значений выглядит следующим образом:

flex-direction: rowНаправление row (строка, ряд) для локали LTR flex-direction-row: reverseНаправление row-reverse (реверсивная строка) для локали LTR flex-direction: columnНаправление column (столбец, колонка) flex-direction-column: reverseНаправление column-reverse (реверсивный столбец)

Свойство justify-content

Вы можете указать flex-контейнеру, каким образом будут выравниваться его дочерние элементы вдоль главной оси. Как правило, это помогает распределить лишнее свободное пространство, если flex-элементы негибкие, либо гибкие, но достигшие максимального размера.

Свойство justify-content применяется к flex-контейнеру, и принимает такие значения:

  • flex-start (значение по умолчанию) — flex-элементы прижимаются к началу главной оси.
  • flex-end — flex-элементы прижимаются к концу главной оси.
  • center — flex-элементы центрируются по главной оси.
  • space-between — первый flex-элемент находится в начале главной оси, последний flex-элемент — в ее конце, а все остальные flex-элементы равномерно распределяются в пределах оставшегося пространства.
  • space-around — все flex-элементы равномерно распределяются на главной оси, при этом свободное пространство поровну делится между ними.

Работа этих значений проиллюстрирована ниже:

justify-content: flex-startjustify-content: flex-start justify-content: flex-endjustify-content: flex-end justify-content: centerjustify-content: center justify-content: space-betweenjustify-content: space-between justify-content: space-aroundjustify-content: space-around

Свойство align-items

Align-items — еще одно свойство, применяемое к flex-контейнеру для выравнивания его дочерних элементов. Только на этот раз выравнивание происходит не по главной оси, а по поперечной. Рассмотрим список значений:

  • stretch (значение по умолчанию) — flex-элементы растягиваются вдоль поперечной оси (если при этом указаны свойства min-width/max-width, они принимаются во внимание).
  • flex-start — flex-элементы прижимаются к началу поперечной оси.
  • flex-end — flex-элементы прижимаются к концу поперечной оси.
  • center — flex-элементы центрируются по поперечной оси.
  • baseline — flex-элементы выравниваются по своим базовым линиям.

Примеры для лучшего понимания информации:

align-items: stretchalign-items: stretch align-items: flex-startalign-items: flex-start align-items: flex-endalign-items: flex-end align-items: centeralign-items: center align-items: baselinealign-items: baseline

Свойство flex-wrap

На примерах выше были показаны примитивные примеры с использованием лишь одной строки (столбца) flex-контейнера. Да, по умолчанию так и есть: flex-контейнер содержит в себе лишь одну линию. Но благодаря свойству flex-wrap можно активировать многострочность во flex-контейнере. Свойство принимает следующие значения:

  • nowrap (значение по умолчанию) — flex-элементы размещаются в одной линии, слева направо (либо справа налево для локации RTL).
  • wrap — flex-элементы выстраиваются горизонтально в несколько рядов (при условии, что они не помещаются в один ряд). Направление элементов — слева направо (или справа налево для RTL).
  • wrap-reverse — принцип действия идентичен предыдущему свойству, с той лишь разницей, что расположение flex-элементов происходит в реверсном порядке.
flex-wrap: nowrapflex-wrap: nowrap flex-wrap: wrapflex-wrap: wrap flex-wrap: wrap-reverseflex-wrap: wrap-reverse

Свойство flex-flow

Свойство flex-flow — это, по сути, сокращенная запись свойств flex-direction и flex-wrap. Вы можете одной строкой задать направление главной оси и определить многострочность flex-контейнера. В свойстве указываются два значения через пробел: одно для flex-direction, второе для flex-wrap. Пример:


flex-flow: column wrap-reverse;

Свойство align-content

Данное свойство работает только в том случае, если flex-контейнер поддерживает многострочность. При помощи align-content можно указать, как будут выравниваться ряды flex-элементов по вертикали. Доступные значения:

  • stretch (значение по умолчанию) — ряд flex-элементов растягивается по вертикали, пока не упрется в следующий ряд (если при этом указаны свойства min-width/max-width, они принимаются во внимание).
  • flex-start — ряды flex-элементов прижимаются к началу flex-контейнера.
  • flex-end — ряды flex-элементов прижимаются к концу flex-контейнера.
  • center — ряды flex-элементов вертикально центрируются во flex-контейнере.
  • space-between — первый ряд flex-элементов находится в начале flex-контейнера, последний ряд flex-элементов — в конце, а все остальные ряды равномерно распределяются в пределах оставшегося пространства.
  • space-around — все ряды flex-элементов равномерно распределяются в вертикальном пространстве flex-контейнера, при этом свободное пространство поровну делится между ними.
align-content: stretchalign-content: stretch align-content: flex-startalign-content: flex-start align-content: flex-endalign-content: flex-end align-content: centeralign-content: center align-content: space-betweenalign-content: space-between align-content: space-aroundalign-content: space-around

Напомним, что все перечисленные выше свойства применяются именно к flex-контейнеру. В следующем уроке мы рассмотрим свойства, предназначенные для flex-элементов.

Свойства flex-элементов | WebReference

order

Свойство order управляет порядком, в котором дочерние элементы появляются внутри flex-контейнера. По умолчанию они располагаются в том порядке, как добавлены исходно во flex-контейнер.

Значения
.flex-item {
  order: <целое число>;
}

flex-элементы могут быть переупорядочены с помощью этого простого свойства без изменения кода HTML.

Значение по умолчанию: 0.

flex-grow

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

Значения
.flex-item {
  flex-grow: <число>;
}

Если все flex-элементы имеют одинаковое значение flex-grow, то все элементы будут иметь и одинаковый размер в контейнере.

Второй flex-элемент занимает больше места относительно размера других flex-элементов.

Значение по умолчанию: 0.

Отрицательные числа недопустимы.

flex-shrink

flex-shrink задаёт коэффициент сжатия, который определяет, насколько flex-элемент будет сжиматься относительно остальных flex-элементов во flex-контейнере, при распределении отрицательного свободного пространства.

Значения
.flex-item {
  flex-shrink: <число>;
}

По умолчанию все flex-элементы могут быть сжаты, но если мы установим значение flex-shrink нулевым (без сжатия), то элементы сохраняют исходный размер.

Значение по умолчанию: 1.

Отрицательные числа недопустимы.

flex-basis

Это свойство принимает те же значения, что и свойства width и height, и определяет начальный основной размер flex-элемента, до того, как свободное пространство распределяется в соответствии с коэффициентами.

Значения
.flex-item {
  flex-basis: auto | <ширина>;
}

flex-basis указан для четвёртого flex-элемента и диктует его начальный размер.

Значение по умолчанию: auto.

flex

Это свойство является сокращением для свойств flex-grow, flex-shrink и flex-basis. Крое других значений также можно установить auto (1 1 auto) и none (0 0 auto).

Значения
.flex-item {
  flex: none | auto | [ <flex-grow> <flex-shrink>? || <flex-basis> ];
}

Значение по умолчанию: 0 1 auto.

W3C рекомендует использовать сокращённое свойство flex, вместо отдельных свойств, поскольку flex правильно сбрасывает любые неуказанные компоненты для типового использования.

align-self

Свойство align-self позволяет переопределить выравнивание по умолчанию (или значение, указанное через align-items) для отдельных flex-элементов. Для понимания доступных значений обратитесь к описанию align-items для flex-контейнера.

Значения
.flex-item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

Для третьего и четвёртого flex-элементов переопределено выравнивание через свойство align-self.

Значение по умолчанию: auto.

Значение auto для align-self вычисляется как значение align-items родительского элемента или stretch, если родитель отсутствует.

Замечания

Свойства float, clear и vertical-align не оказывают влияния на flex-элемент и не вырывают его из потока.

Автор и редакторы

Автор: Димитар Стоянов

Последнее изменение: 15.05.2018

Редакторы: Влад Мержевич

Курс по вёрстке сайта на CSS Grid

Размер flex-элемента (свойство flex: flex-grow, flex-shrink, flex-basis) | Flexbox

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


flex

<‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’>flex — это сокращённая запись трёх свойств, значения по умолчанию которых:
  • flex-grow: 0;
  • flex-shrink: 1;
  • flex-basis: auto;
none0 0 auto
initial0 1 auto
inheritнаследует значение родителя
unset0 1 auto

Синтаксис:



flex: none;


flex: initial;


flex: 10px;
flex: auto;
flex: content;


flex: 1;




flex: 1 10px;


flex: 1 1;




flex: 1 1 10px;

Пример вёрстки Flexbox:

Я всегда буду занимать 7em

Я буду занимать 7em, но могу поубавить

Я заполню оставшуюся 1/3

Я заполню оставшиеся 2/3

<style>
.raz {
  display: flex;
  overflow: auto;
  text-align: center;
}
.raz div:nth-child(1) {
  flex: none;
  width: 7em;
  background: yellow;
}
.raz div:nth-child(2) {
  width: 7em;
  background: orange;
}
.raz div:nth-child(3) {
  flex: 1;
  background: red;
}
.raz div:nth-child(4) {
  flex: 2;
  background: purple;
}
</style>

<div>
  <div>Я всегда буду занимать 7em</div>
  <div>Я буду занимать 7em, но могу поубавить</div>
  <div>Я заполню оставшуюся 1/3</div>
  <div>Я заполню оставшиеся 2/3</div>
</div>

flex-basis: исходный размер flex-элемента

<style>
.raz {
  display: flex;
  background: green;
}
.raz div {
  flex: 0 0 auto;
  min-height: 1.6em;
  background: yellow;
}
</style>

<div>
  <div></div>
</div>

Если flex-direction имеет значения row или row-reverse, то flex-basis определяет ширину flex-элемента (заменяет свойство width), если column или column-reverse — высоту flex-элемента (заменяет свойство height).

Свойства width/height игнорируются, если flex-basis не имеет значение auto.

Свойство flex-basis имеет преимущество перед width/height в удобной записи в одну строку в составе свойства flex. При overflow: visible; (по умолчанию) есть отличие при переполнении flex-элемента (искл., IE):

overflow: hidden;

????????????????????????????????????????????????

????????????????????????????????????????????????

<style>
.raz,
.dva {
  display: flex;
  background: green;
}
.raz div,
.dva div {
  overflow: hidden;
  background: yellow;
}
.raz div {
  flex: 0 0 7em;
}
.dva div {  
  flex: 0 0 auto;
  width: 7em;
}
</style>

<div>
  <div>????????????????????????????????????????????????</div>
</div>

<div>
  <div>????????????????????????????????????????????????</div>
</div>

Свойство flex-basis взаимодействует с box-sizing также как width/height в блочной модели:

Как работает свойство flex:

  • если сумма размеров всех flex-элементов меньше размера flex-контейнера, то применяется flex-grow.
  • если сумма размеров всех flex-элементов равна размеру flex-контейнера, то не применяются ни flex-grow, ни flex-shrink.
  • если сумма размеров всех flex-элементов больше размера flex-контейнера, то применяется flex-shrink.
flex-basis:
<style>
.raz {
  display: flex;
  text-align: center;
}
.raz div {
  flex: 3 3 50%; 
  background: yellow;
}
.raz div:nth-child(2) {
  flex: 1 1 50%;
  background: orange;
}
</style>

<div>
  <div>3 3 50%</div>
  <div>1 1 50%</div>
</div>

flex-grow: доля от поначалу незанятого пространства flex-контейнера, увеличивающая flex-элемент

<style>
.raz {
  display: flex;
}
.raz div {
  min-height: 1.6em;
}
.raz div:nth-child(1) {
  flex: 0 0 auto;
  background: yellow;
}
.raz div:nth-child(2) {
  flex: 1 0 auto;
  background: orange;
}
.raz div:nth-child(3) {
  flex: 1 0 auto;
  background: red;
}
</style>

<div>
  <div></div>
  <div></div>
  <div></div>
</div>

Если flex-grow имеет значение 0, то flex-элемент не будет увеличиваться в случае недозаполненности flex-контейнера, он будет опираться на значение flex-basis. Иначе flex-элемент увеличится на величину, равную величине поначалу незанятого пространства flex-контейнера.

<style>
.raz,
.dva {
  display: flex;
  background: green;
}
.raz div {
  flex: 0 0 7em;
  background: yellow;
}
.dva div {
  flex: 1 0 7em; 
  background: yellow;
}
</style>

<div>
  <div>0 0 7em</div>
</div>

<div>
  <div>1 0 7em</div>
</div>

Если flex-элементов несколько, то они вне зависимости от исходного размера разделят между собой поначалу незанятое пространство flex-контейнера согласно указанным в flex-grow пропорциям.


flex-shrink: доля от поначалу выходящего за пределы flex-контейнера пространства, уменьшающая flex-элемент

<style>
.raz {
  display: flex;
}
.raz div {
  min-height: 1.6em;
  width: 50%;  
}
.raz div:nth-child(1) {
  flex: 0 1 auto;
  background: yellow;
}
.raz div:nth-child(2) {
  flex: 0 1 auto;
  background: orange;
}
.raz div:nth-child(3) {
  flex: 0 1 auto;
  background: red;
}
</style>

<div>
  <div></div>
  <div></div>
  <div></div>
</div>

Если flex-shrink имеет значение 0, то flex-элемент не будет уменьшаться в случае переполнения flex-контейнера, он будет опираться на значение flex-basis. Иначе flex-элемент уменьшится на величину, равную величине поначалу выходящего за flex-контейнер пространства.

<style>
.raz,
.dva {
  display: flex;
  width: 66%; 
  border: solid green;
  background: green;
}
.raz div {
  flex: 0 0 150%;
  background: yellow;
}
.dva div {
  flex: 0 1 150%;
  background: yellow;
}
</style>

<div>
  <div>0 0 150%</div>
</div>

<div>
  <div>0 1 150%</div>
</div>

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

Flex-элемент не будет ограничен рамками родителя, когда flex-basis/width/height примут значение auto, а flex-shrink/max-width/max-height0 (искл., Mozilla Firefox).

0 0 auto 1 0 auto 2 0 auto 3 0 auto 4 0 auto 5 0 auto 6 0 auto

<style>
.raz {
  display: flex;
  width: 30%;
  border: solid green;
  background: green;
}
.raz div {
  flex: 0 0 auto;
  background: yellow;
}
</style>

<div>
  <div>0 0 auto 1 0 auto 2 0 auto 3 0 auto 4 0 auto 5 0 auto 6 0 auto</div>
</div>

Когда длину задаёт flex-basis, а не max-width/max-height/width/height при overflow: visible; (по умолчанию) flex-shrink сожмёт flex-элемент настолько, насколько позволит ему содержимое flex-элемента.

????????????????????????????????????????????????

????????????????????????????????????????????????

????????????????????????????????????????????????

????????????????????????????????????????????????

<style>
.raz,
.dva,
.tri,
.chetyre {
  display: flex;
  width: 30%;
  border: solid green;
  background: green;
}
.raz div {
  flex: 0 1 0;  
  background: yellow;
}
.dva div {
  flex: 0 1 auto;
  width: 100%;
  background: yellow;
}
.tri div {
  flex: 0 1 0;
  max-width: 100%;
  background: yellow;
}
.chetyre div {
  flex: 1 1 0;
  overflow: auto;
  background: yellow;
}
</style>

<div>
  <div>????????????????????????????????????????????????</div>
</div>

<div>
  <div>????????????????????????????????????????????????</div>
</div>

<div>
  <div>????????????????????????????????????????????????</div>
</div>

<div>
  <div>????????????????????????????????????????????????</div>
</div>

Распределение пространства flex-контейнера в цифрах

Flex-элементы имеют относительную связь друг с другом

 жёлтый в 1,5 раза больше, чем  оранжевый:
3 : 2 = 1,5

 жёлтый в 3 раза больше, чем  красный
3 : 1 = 3

Как рассчитывается ширина элементов в flex-контейнере:

 flex-grow : (flex-grow + flex-grow + flex-grow) * flex-контейнер = 3 : (3 + 2 + 1) * flex-контейнер = 1/2 flex-контейнер

 flex-grow : (flex-grow + flex-grow + flex-grow) * flex-контейнер = 2 : (3 + 2 + 1) * flex-контейнер = 1/3 flex-контейнер

 flex-grow : (flex-grow + flex-grow + flex-grow) * flex-контейнер = 1 : (3 + 2 + 1) * flex-контейнер = 1/6 flex-контейнер
<style>
.raz {
  display: flex;
  text-align: center;
}
.raz div {
  background: yellow;
  flex: 3 0 0;
}
.raz div:nth-child(2) {
  flex: 2 0 0;
  background: orange;
}
.raz div:nth-child(3) {
  flex: 1 0 0;
  background: red;
}
</style>

<div>
  <div>3 0 0</div>
  <div>2 0 0</div>
  <div>1 0 0</div>
</div>

Если flex-элементы не заполняют всё пространство flex-контейнера, то сперва определяется свободное пространство в flex-контейнере (flex-контейнер - (flex-basis + flex-basis + flex-basis)), затем оно увеличивает flex-элементы согласно заявленным в flex-grow долям

3 0 20px

2 0 10px

2 0 70px

Как рассчитывается ширина элементов в flex-контейнере:

 flex-grow : (flex-grow + flex-grow + flex-grow) * (flex-контейнер - (flex-basis + flex-basis + flex-basis)) + flex-basis = 3 : (3 + 2 + 2) * (flex-контейнер - (20 + 10 + 70)) + 20 = 3/7 (flex-контейнер - 100) + 20

 flex-grow : (flex-grow + flex-grow + flex-grow) * (flex-контейнер - (flex-basis + flex-basis + flex-basis)) + flex-basis = 2 : (3 + 2 + 2) * (flex-контейнер - (20 + 10 + 70)) + 10 = 2/7 (flex-контейнер - 100) + 10

 flex-grow : (flex-grow + flex-grow + flex-grow) * (flex-контейнер - (flex-basis + flex-basis + flex-basis)) + flex-basis = 2 : (3 + 2 + 2) * (flex-контейнер - (20 + 10 + 70)) + 70 = 2/7 (flex-контейнер - 100) + 70

* сначала выполняется умножение/деление, потом сложение/вычитание: 2+2*2=6
<style>
.raz {
  display: flex;
  text-align: center;
}
.raz div {
  flex: 3 0 20px;
  background: yellow;
}
.raz div:nth-child(2) {
  flex: 2 0 10px;
  background: orange;
}
.raz div:nth-child(3) {
  flex: 2 0 70px;
  background: red;
}
</style>

<div>
  <div>3 0 20px</div>
  <div>2 0 10px</div>
  <div>2 0 70px</div>
</div>

Ширина/высота flex-элемента не превышает значения свойств max-width/max-height

3 0 20px

2 0 10px

2 0 70px

Как рассчитывается ширина элементов в flex-контейнере:

 flex-grow : (flex-grow + flex-grow) * (flex-контейнер - (flex-basis + flex-basis + max-width)) + flex-basis = 3 : (3 + 2) * (flex-контейнер - (20 + 10 + 100)) + 20 = 3/5 (flex-контейнер - 130) + 20

 flex-grow : (flex-grow + flex-grow) * (flex-контейнер - (flex-basis + flex-basis + max-width)) + flex-basis = 2 : (3 + 2) * (flex-контейнер - (20 + 10 + 100)) + 10 = 2/5 (flex-контейнер - 130) + 10

 max-width = 100
<style>
.raz {
  display: flex;
  text-align: center;
}
.raz div {
  flex: 3 0 20px;
  background: yellow;
}
.raz div:nth-child(2) {
  flex: 2 0 10px;
  background: orange;
}
.raz div:nth-child(3) {
  max-width: 100px;
  flex: 2 0 70px;
  background: red;
}
</style>

<div>
  <div>3 0 20px</div>
  <div>2 0 10px</div>
  <div>2 0 70px</div>
</div>

Если размера flex-контейнера не хватает для flex-элементов, то сперва определяется сколько требуется пространства (flex-basis + flex-basis + flex-basis - flex-контейнер), затем оно уменьшает flex-элементы согласно заявленным в flex-shrink долям

0 3 500px

0 2 100px

0 2 400px

Как рассчитывается ширина элементов в flex-контейнере:

 flex-basis - flex-shrink * flex-basis : (flex-shrink * flex-basis + flex-shrink * flex-basis + flex-shrink * flex-basis) * (flex-basis + flex-basis + flex-basis - flex-контейнер) = 500 - 3 * 500 : (3 * 500 + 2 * 100 + 2 * 400) * (500 + 100 + 400 - flex-контейнер) = 500 - 15/25 (1000 - flex-контейнер) = 15/25 flex-контейнер - 100

 flex-basis - flex-shrink * flex-basis : (flex-shrink * flex-basis + flex-shrink * flex-basis + flex-shrink * flex-basis) * (flex-basis + flex-basis + flex-basis - flex-контейнер) = 100 - 2 * 100 : (3 * 500 + 2 * 100 + 2 * 400) * (500 + 100 + 400 - flex-контейнер) = 100 - 2/25 (1000 - flex-контейнер) = 2/25 flex-контейнер + 20

 flex-basis - flex-shrink * flex-basis : (flex-shrink * flex-basis + flex-shrink * flex-basis + flex-shrink * flex-basis) * (flex-basis + flex-basis + flex-basis - flex-контейнер) = 400 - 2 * 400 : (3 * 500 + 2 * 100 + 2 * 400) * (500 + 100 + 400 - flex-контейнер) = 400 - 8/25 (1000 - flex-контейнер) = 8/25 flex-контейнер + 80
<style>
.raz {
  display: flex;
  text-align: center;
}
.raz div {
  flex: 0 3 500px;
  background: yellow;
}
.raz div:nth-child(2) {
  flex: 0 2 100px;
  background: orange;
}
.raz div:nth-child(3) {
  flex: 0 2 400px;
  background: red;
}
</style>

<div>
  <div>3 0 20px</div>
  <div>2 0 10px</div>
  <div>2 0 70px</div>
</div>

Ширина/высота flex-элемента не может быть менее значения свойств min-width/min-height

Как рассчитывается ширина элементов в flex-контейнере:

 flex-basis - flex-shrink * flex-basis : (flex-shrink * flex-basis + flex-shrink * flex-basis) * (flex-basis + flex-basis + min-width - flex-контейнер) = 500 - 3 * 500 : (3 * 500 + 2 * 100) * (500 + 100 + 380 - flex-контейнер) = 500 - 15/17 (980 - flex-контейнер) = 15/17 flex-контейнер - 364

 flex-basis - flex-shrink * flex-basis : (flex-shrink * flex-basis + flex-shrink * flex-basis) * (flex-basis + flex-basis + min-width - flex-контейнер) = 100 - 2 * 100 : (3 * 500 + 2 * 100) * (500 + 100 + 380 - flex-контейнер) = 100 - 2/17 (980 - flex-контейнер) = 2/17 flex-контейнер - 15 

 min-width = 380
<style>
.raz {
  display: flex;
  text-align: center;
}
.raz div {
  flex: 0 3 500px;
  background: yellow;
}
.raz div:nth-child(2) {
  flex: 0 2 100px;
  background: orange;
}
.raz div:nth-child(3) {
  flex: 0 2 400px;
  min-width: 380px;
  background: red;
}
</style>

<div>
  <div>3 0 20px</div>
  <div>2 0 10px</div>
  <div>2 0 70px</div>
</div>

Используемые материалы:

  1. flex [MDN]
  2. Flexbox adventures [Chris Coyier]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *