Как сделать флекс элементы одинакового размера

Обновлено: 05.07.2024

Модель верстки известная как Flexbox (флексы), становится все популярнее. В первую очередь за счет удобного использования при создании каркасов и верстки отдельных элементов HTML страницы. Во вторую, за счет совершенно новых возможностей. В этой статье я попробую разобраться во всех тонкостях Flexbox, сделать своего рода документацию (шпаргалку) по флексам и доступно поделиться знаниями с вами.

CSS Flexible Box Layout Module (CSS модуль для макетов с гибкими блоками), коротко flexbox (Флексбокс), создана, чтобы убрать недостатки при создании самых разных HTML конструкций, в том числе адаптированных под разную ширину и высоту, и сделать верстку логичной и простой. А логичный подход, как правило работает в неожиданных местах, там где результат не проверялся - логика наше все!

Flexbox позволяет элегантно контролировать самые разные параметры элементов внутри контейнера: направление, порядок, ширину, высоту, выравнивание вдоль и поперек, распределение свободного места, растяжение и сжатие элементов.

  • Базовые знания
  • CSS свойства Flexbox
  • Для контейнера
  • display:
  • flex-direction:
  • flex-wrap:
  • flex-flow: direction wrap
  • justify-content:
  • align-content:
  • align-items:
  • column-gap:
  • gap:
  • Для элементов контейнера
  • flex-grow:
  • flex-shrink:
  • flex-basis:
  • flex:
  • align-self:
  • order:
  • Заметки
  • Примеры Flex верстки
  • Поддержка браузерами - 99%
  • Видео
  • Полезные ссылки по Flex

Базовые знания


FlexBox состоит из Контейнера и его Дочерних элементов (items) (гибких элементов).

Главная ось - главное направление движения элементов внутри контейнера. Направление главной оси можно изменить с помощью свойства flex-direction. Обратите внимание, что при смене осей, меняются только направления движения блоков внутри, а начало, конец и размер контейнера остаются прежними.

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

Поперечная ось - направление движения элементов, когда они не умещаются в контейнер по направлению главной оси. Поперечная ось всегда перпендикулярна (⊥) главной.

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

Для включения flexbox, любому HTML элементу достаточно присвоить css свойство display:flex; или display:inline-flex; .

После включения flex свойства, внутри контейнера создаются две оси: главная и поперечная (перпендикулярная (⊥), кросс ось). Все вложенные элементы (первого уровня) выстраиваются по главной оси. По умолчанию главная ось горизонтальная и имеет направление слева направо (→), а кросс ось соответственно вертикальная и направлена сверху вниз (↓).


CSS свойства, которые могут влиять на модель построения макета: float , clear , vertical-align , columns не работают во flex конструкции. Тут используется другая модель построения макета и эти css свойства просто игнорируются.

CSS свойства Flexbox

Flexbox содержит разные css правила для управления всей flex конструкцией. Одни нужно применять к основному контейнеру, а другие к элементам этого контейнера.

Для контейнера

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

  • flex - элемент растягивается на всю ширину и имеет свое полное пространство среди окружающих блоков. Происходит перенос строк в начале и в конце блока.
  • inline-flex - элемент обтекается другими элементами. При этом его внутренняя часть форматируется как блочный элемент, а сам элемент — как встроенный.

flex и inline-flex отличаются тем что по-разному взаимодействуют с окружающими элементами, подобно display:block и display:inline-block .

Изменяет направление главной оси контейнера. Поперечная ось меняется соответственно.

  • row (default) - направление элементов слева направо (→)
  • column - направление элементов сверху вниз (↓)
  • row-reverse - направление элементов справа налево (←)
  • column-reverse - направление элементов снизу вверх (↑)

Нужно понимать, что при переходе с row на column или с row-reverse на column-reverse меняется только направление осей и больше ничего. Начало и конец расположения блоков остается неизменным (см. картинку в начале). Т.е. если при row элементы начинали свой путь справа/сверху, то при column все останется также - изменится только направление. (см. пример свойства flex-wrap)

Управляет переносом непомещающихся в контейнер элементов.

  • nowrap (default) - вложенные элементы располагаются в один ряд (при direction=row) или в одну колонку (при direction=column) независимо от того помещаются они в контейнер или нет.
  • wrap - включает перенос элементов на следующий ряд, если они не помещаются в контейнер. Так включается движение элементов по поперечной оси.
  • wrap-reverse - тоже что wrap только перенос будет не вниз, а вверх (в обратном направлении).

Объединяет оба свойства flex-direction и flex-wrap . Они часто используются вместе, поэтому чтобы писать меньше кода было создано свойство flex-flow .

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

Выравнивает элементы по основной оси: если direction=row, то по горизонтали, а если direction=column, то по вертикали.

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

Выравнивает ряды, в которых находятся элементы по поперечной оси. То же что 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-content , а элементы внутри этих рядов (строк) через align-items и все это по поперечной оси. По главной оси такого разделения нет, там нет понятия рядов и элементы выравниваются через justify-content .

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

Задает размер промежутка между элементами контейнера. Соответственно:

  • column-gap: — раздвигает только колонки.
  • gap: — раздвигает и колонки и ряды.

Размеры можно указать в абсолютных или относительных величинах: px, em, . или в % .

Поддержка gap ( у column-gap поддержка точно такая же ):

Для элементов контейнера

Задает коэффициент увеличения элемента при наличии свободного места в контейнере. По умолчанию 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-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

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

По умолчанию: auto

Иногда лучше установить ширину элемента жестко через привычное свойство width . Например, width: 50%; будет означать, что элемент внутри контейнера будет ровно 50%, однако при этом все также будут работать свойства flex-grow и flex-shrink . Такое может быть нужно, когда элемент растягивается контентом внутри него, больше указанного во flex-basis. Пример смотрите в заметках.

Короткая запись трех свойств: flex-grow flex-shrink flex-basis .

По умолчанию: flex: 0 1 auto

Однако можно указать и одно, и два значения:

Позволяет изменить свойство align-items , только для отдельного элемента.

По умолчанию: от align-items контейнера

  • stretch - элемент растягиваются заполняя строку полностью
  • flex-start - элемент прижимаются к началу строки
  • flex-end - элемент прижимаются к концу строки
  • center - элемент выравниваются по центру строки

baseline - элемент выравниваются по базовой линии текста

Позволяет менять порядок (позицию, положение) элемента в общем ряду.

По умолчанию: 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.

По возможности все же отдавайте предпочтение flex-basis. Используйте width только когда не подходит flex-basis.

Отличие flex-basis от width - баг или фича?

Контент внутри flex элемента распирает его и не может выйти за его пределы. Однако если установить ширину через width или max-width , а не flex-basis , то элемент внутри flex контейнера сумеет выйти за пределы этого контейнера (иногда нужно именно такое поведение). Пример:

Примеры Flex верстки

В примерах нигде не используются префиксы для кроссбраузерности. Сделал я так для удобного чтения css. Поэтому примеры смотрите в последних версиях Chrome или Firefox.

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

Или так, без блока внутри:

Чтобы расположить элементы контейнера по краям и произвольно выбрать элемент после которого будет разрыв, нужно использовать свойство margin-left:auto или margin-right:auto .

Сделаем меню в самом верху страницы. На широком экране оно должно быть справа. На среднем выравниваться по середине. А на маленьком каждый элемент должен быть на новой строке.

Этот пример показывает как быстро и удобно сделать 3 колонки, которые при сужении будут превращаться в 2 и затем в 1.

Обратите внимание, что сделать это можно без использования media правил, все на flex.

Допустим нам нужно вывести 3 блока, один большой и два маленьких. При этом нужно чтобы блоки подстраивались под маленькие экраны. Делаем:

Этот пример показывает как быстро можно сделать симпатичный аккордеон с картинками на flex. Обратите внимание на свойство transition для flex.

Задача сделать гибкий блок. Так чтобы начало текста в каждом блоке находилось на одной линии по горизонтали. Т.е. при сужении ширины, блоки растут в высоту. Нужно, чтобы картинка была вверху, кнопка всегда внизу, а текст по середине начинался по одной горизонтальной линии.

Для решения этой задачи, сами блоки растягиваются флексом и им установлена максимально возможная ширина. Каждый внутренний блок также является флекс конструкцией, с повернутой осью flex-direction:column; и элемент в середине (где находится текст) растягивается flex-grow:1; чтобы заполнить всё свободное пространство, так достигается результат - текст начинался с одной линии.

Еще примеры

Поддержка браузерами - 99%

Полной поддержки разумеется нет, однако все современные браузеры поддерживают flexbox конструкции. Для некоторых все еще нужно указывать префиксы.

Чтобы знать какие префиксы актуальны на сегодня (июнь. 2019), приведу пример всех flex правил с нужными префиксами:

Лучше если свойства с префиксами будут идти до оригинального свойства.
В этом списке нет ненужных на сегодня (по caniuse) префиксов, но вообще префиксов больше.

Видео

Ну и не забывайте про видео, там порой тоже интересно и понятно. Вот парочка популярных:

CSS Flexbox — это технология для создания сложных гибких макетов за счёт правильного размещения элементов на странице. О самой технологии пишут здесь. Мы же решили объяснить возможности CSS Flexbox с использованием гифок.

Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.

display: flex

На ней размещено 4 div разных размеров, которые находятся внутри серого div . У каждого div есть свойство display: block . Поэтому каждый блок занимает всю ширину строки. Чтобы начать работать с CSS Flexbox, нужно сделать контейнер flex-контейнером. Делается это так:

Так у блоков появилось свойство flex-контекст, которое в дальнейшем позволит ими управлять гораздо проще, чем с использованием стандартного CSS.

flex-direction

У flex-контейнера есть две оси: главная и перпендикулярная ей.

CSS Flexbox: оси flex-контейнера

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

Обратите внимание, что flex-direction: column не выравнивает блоки по оси, перпендикулярной главной. Главная ось сама меняет своё расположение, и теперь направлена сверху вниз.

Есть ещё парочка свойств для flex-direction : row-reverse и column-reverse .

justify-content

Отвечает за выравнивание элементов по главной оси:

Justify-content может принимать 5 значений:

  1. flex-start
  2. flex-end
  3. center
  4. space-between
  5. space-around

Space-between задаёт одинаковое расстояние между блоками, но не между контейнером и блоками. Space-around также задаёт одинаковое расстояние между блоками, но теперь расстояние между контейнером и блоками равно половине расстояния между блоками.

align-items

Если justify-content работает с главной осью, то align-items работает с осью, перпендикулярной главной оси. Вернёмся к flex-direction: row и пройдёмся по командам align-items :

  1. flex-start
  2. flex-end
  3. center
  4. stretch
  5. baseline

Стоит заметить, что для align-items: stretch высота блоков должна быть равна auto . Для align-items: baseline теги параграфа убирать не нужно, иначе получится так:


Чтобы получше разобраться в том, как работают оси, объединим justify-content с align-items и посмотрим, как работает выравнивание по центру для двух свойств flex-direction :

align-self

Позволяет выравнивать элементы по отдельности:

Для двух блоков применим align-self , а для остальных — align-items: center и flex-direction: row .

flex-basis

Отвечает за изначальный размер элементов до того, как они будут изменены другими свойствами CSS Flexbox:

flex-basis влияет на размер элементов вдоль главной оси. Давайте посмотрим, что случится, если мы изменим направление главной оси:

Заметьте, что нам пришлось изменить и высоту элементов: flex-basis может определять как высоту элементов, так и их ширину в зависимости от направления оси.

flex-grow

Это свойство немного сложнее. Для начала зададим блокам одинаковую ширину в 120px:

flex-grow

По умолчанию значение flex-grow равно 0. Это значит, что блокам запрещено увеличиваться в размерах. Зададим flex-grow равным 1 для каждого блока:

CSS Flexbox: flex-grow

Теперь блоки заняли оставшееся место в контейнере. Но что значит flex-grow: 1 ? Попробуем сделать flex-grow равным 999:


И… ничего не произошло. Так получилось из-за того, что flex-grow принимает не абсолютные значения, а относительные. Это значит, что не важно, какое значение у flex-grow , важно, какое оно по отношению к другим блокам:

Вначале flex-grow каждого блока равен 1, в сумме получится 6. Значит, наш контейнер разделён на 6 частей. Каждый блок будет занимать 1/6 часть доступного пространства в контейнере. Когда flex-grow третьего блока становится равным 2, контейнер делится на 7 частей: 1 + 1 + 2 + 1 + 1 + 1. Теперь третий блок занимает 2/7 пространства, остальные — по 1/7. И так далее.

flex-grow работает только для главной оси, пока мы не изменим её направление.

flex-shrink

Прямая противоположность flex-grow . Определяет, насколько блоку можно уменьшиться в размере. flex-shrink используется, когда элементы не вмещаются в контейнер. Вы определяете, какие элементы должны уменьшиться в размерах, а какие — нет. По умолчанию значение flex-shrink для каждого блока равно 1. Это значит, что блоки будут сжиматься, когда контейнер будет уменьшаться.

Зададим flex-grow и flex-shrink равными 1:

Теперь поменяем значение flex-shrink для третьего блока на 0. Ему запретили сжиматься, поэтому его ширина останется равной 120px:

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

Заменяет flex-grow , flex-shrink и flex-basis . Значения по умолчанию: 0 (grow) 1 (shrink) auto (basis) .

Создадим два блока:

У обоих одинаковый flex-basis . Это значит, что оба будут шириной в 300px (ширина контейнера: 600px плюс margin и padding ). Но когда контейнер начнет увеличиваться в размерах, первый блок (с большим flex-grow ) будет увеличиваться в два раза быстрее, а второй блок (с наибольшим flex-shrink ) будет сжиматься в два раза быстрее:

Ещё больше возможностей свойства вы можете найти в анимированном руководстве по CSS flex​.

Дополнительно

Как с CSS Flexbox меняется размер?

Когда увеличивается первый блок, он не становится в два раза больше второго, и когда уменьшается второй, он также не становится в два раза меньше первого. Это происходит из-за того, что flex-grow и flex-shrink отвечают за темп роста и сокращения.

Немного математики

Начальный размер контейнера: 640px. Вычтем по 20px с каждой стороны для padding , и у нас останется 600px для двух блоков. Когда ширина контейнера становится равной 430px (потеря в 210px), первый блок ( flex-shrink: 1 ) теряет 70px. Второй блок ( flex-shrink: 2 ) теряет 140px. Когда контейнер сжимается до 340px, мы теряем 300px. Первый блок теряет 100px, второй — 200px. То же самое происходит и с flex-grow .

Если вы также интересуетесь CSS Grid, можете ознакомиться с нашей статьёй, где мы рассматриваем Flexbox и Grid.

Модель flexbox-разметки связана с определенным значением CSS-свойства display родительского элемента (flex-контейнер), содержащего внутри себя дочерние блоки (flex-элементы).

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


Направление выстраивания flex-элементов

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

Другие значения свойства flex-direction — row-reverse (влево), column (вниз), column-reverse (вверх).


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


Чтобы разрешить перенос flex-элементов на новые линии (если им не хватает места в текущей линии):


Свойства flex-direction и flex-wrap можно указать с помощью универсального свойства flex-flow :

Выравнивание flex-элементов вдоль оси

Выравнивание элементов вдоль главной оси

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


Другие значения свойства justify-content :

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


Выравнивание элементов вдоль поперечной оси

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


Другие значения свойства align-items :

  • flex-start — относительно начала поперечной оси
  • flex-end — относительно конца поперечной оси
  • baseline — относительно базовой линии
  • center — по центру


Свойство align-self , заданное для определенного элемента, позволяет перезаписать свойство align-items , заданное для всех элементов в контейнере:

Выравнивание линий flex-контейнера

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


Другие значения свойства align-content :

  • flex-start — относительно начала поперечной оси
  • flex-end — относительно конца поперечной оси
  • center — по центру
  • space-between — равномерно, с одинаковым расстоянием между линиями
  • space-around — равномерно, но с добавлением половины пространства перед первой линией и после последней


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

Изменение порядка следования flex-элементов

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


Управление шириной flex-элементов

Свойство flex-basis

Данное свойство предназначено для установления начальной ширины flex-элементу. Задавать значение ширины можно посредством различных единиц измерения, таких как px, %, em и др. По умолчанию данное свойство имеет значение auto — в этом случае ширина элемента будет рассчитываться автоматически на основании его содержимого.

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

Свойство flex-grow

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

В этом примере flex-элементы расположены на одной линии и в ней есть свободное пространство 240px . После установки значений для свойства flex-grow :

  • ширина первого элемента будет увеличена на 1/5 часть свободного пространства
  • ширина первого элемента будет увеличена на 4/5 части свободного пространства



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

По умолчанию CSS свойство flex-grow имеет значение 0 . Это означает, что flex-элемент не может расти (увеличивать свою ширину).

Свойство flex-shrink

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

Ширина flex-контейнера 400px , для отображения flex-элементов необходимо 600px , не хватает 200px . После установки значений больше нуля, уменьшаться могут оба элемента:

  • ширина первого элемента будет уменьшена на 1/4 от тех 200px , которых не хватает
  • ширина второго элемента будет уменьшена на 3/4 от тех 200px , которых не хватает



Значение свойства по умолчанию равно единице. Нулевое значение запрещает уменьшение ширины элемента.

Для удобной установки flex-grow , flex-shrink и flex-basis можно использовать свойство flex . Значение по умолчанию:

Одной из причин быстрого роста популярности flexbox среди веб-разработчиков было то, что впервые были предоставлены адекватные возможности выравнивания. Он предоставил адекватное вертикальное выравнивание, и стало возможным, наконец, легко поместить элемент в центр по вертикали. В этом руководстве детально рассматривается, как выравнивание и распределение работают во Flexbox.

Для центрирования элемента по перекрёстной оси (в данном случае - вертикальной) используется свойство align-items . Для центрирования элемента по главной оси (в данном случае - горизонтально), используется свойство justify-content .

A containing element with another box centered inside it.

На примере ниже можно изменить размер контейнера или вложенного элемента, но элемент всегда останется по центру.

Свойства управления выравниванием

В этом руководстве рассматриваются следующие свойства:

    — управляет выравниванием элементов по главной оси. — управляет выравниванием элементов по перекрёстной оси. — управляет выравниванием конкретного flex элемента по перекрёстной оси. — описывается в спецификации как “упаковка flex строк”; управляет промежутками между flex строками по перекрёстной оси.

Также будет рассмотрены авто-отступы для выравнивания элементов во flexbox.

Замечание: Свойства выравнивания во Flexbox помещены в отдельную спецификацию — CSS Box Alignment Level 3. Ожидается, что данная спецификация в конце концов заменит свойства, определённые во Flexbox Level One.

Перекрёстная ось

Свойства align-items и align-self управляют выравниванием flex элементов по перекрёстной оси: вертикальной для flex-direction установленным в row, и горизонтальной для flex-direction установленным в column .

Рассмотрим выравнивание по перекрёстной оси на простейшем примере. Если установить display: flex у контейнера, все дочерние элементы становятся flex элементами, выстроенными в ряд. Все они по вертикали примут размер самого высокого элемента, который станет определяющим вертикального размера. Если у flex контейнера задана высота, то все элементы растянутся до высоты контейнера, независимо от размера содержимого.

Three items, one with additional text causing it to be taller than the others.

Three items stretched to 200 pixels tall

Все элементы становятся одной высоты, т.к. по умолчанию свойство align-items имеет значение stretch .

Другие возможные значения свойства:

  • align-items: flex-start
  • align-items: flex-end
  • align-items: center
  • align-items: stretch
  • align-items: baseline

В примере ниже значение свойств align-items установлено в stretch . Попробуйте другие значения для понимания их действия.

Выравнивание одного элемента при помощи align-self

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

В следующем примере, у flex контейнера установлено align-items: flex-start , означающее, что все элементы будут выравнены по началу перекрёстной оси. У первого элемента с помощью first-child селектора установлено align-items: stretch ; у следующего элемента с классом selected установлено align-self: center . Можно изменять значение align-items на контейнере или align-self на элементе для изучения их работы.8н

Изменение основной оси

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

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the vertical axis.

Если изменить flex-direction на column, align-items и align-self будут сдвигать элементы влево или вправо.

Three items, the first aligned to flex-start, second to center, third to flex-end. Aligning on the horizontal axis.

Можно попробовать пример ниже, где установлено flex-direction: column .

Выравнивание содержимого по перекрёстной оси — свойство align-content

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

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

Свойство align-content принимает следующие значения:

  • align-content: flex-start
  • align-content: flex-end
  • align-content: center
  • align-content: space-between
  • align-content: space-around
  • align-content: stretch
  • align-content: space-evenly (не описано в спецификации Flexbox)

В примере ниже flex контейнер имеет высоту 400 пикселей - больше, чем необходимо для отображения всех элементов. Значение align-content установлено в space-between , означающее, что свободное пространство разделено между строками, расположенными вплотную к началу и концу контейнера по перекрёстной оси.

Попробуйте другие значения align-content для понимания принципа их работы.

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

Замечание: значение space-evenly не определено в спецификации flexbox и добавлено позже в спецификацию Box Alignment. Поддержка браузерами этого значение не так широка, как значений определённым в спецификации flexbox.

В документации по justify-content на MDN приведено больше деталей о всех значениях и поддержке браузерами.

Выравнивание содержимого по главной оси

Теперь, когда мы увидели, как работает выравнивание по перекрёстной оси, можно посмотреть на главную ось. Здесь нам доступно только одно свойство — justify-content . Это обусловлено тем, что с элементами на главной оси мы работаем только как с группой. Используя свойство justify-content , мы контролируем, что происходит со свободным пространством на главной оси, и требуется ли нам больше пространства, чем нужно для отображения наших элементов.

В нашем первом примере с использованием свойства display: flex , применённым к контейнеру, элементы отображаются как строка и выстраиваются в начале блока. Это обусловлено тем, что свойство justify-content имеет начальное значение flex-start . Все свободное место располагается в конце контейнера.

Three items, each 100 pixels wide in a 500 pixel container. The available space is at the end of the items.

Свойство justify-content может принимать те же самые значения, что и align-content .

  • justify-content: flex-start
  • justify-content: flex-end
  • justify-content: center
  • justify-content: space-between
  • justify-content: space-around
  • justify-content: stretch
  • justify-content: space-evenly (не определено в спецификации Flexbox)

В примере ниже, свойству justify-content задано значение space-between . Все доступное пространство распределяется между элементами после их позиционирования в контейнере. Первый и последний элементы занимают положения в начале и в конце контейнера соответственно.

Если свойство flex-direction имеет значение column , то свойство justify-content распределит доступное пространство в контейнере между элементами.

Выравнивание и режим записи

Необходимо помнить, что при использовании свойств flex-start и flex-end элементы позиционируются в режиме записи. Если свойству justify-content задано значение start и стоит режим записи left-to-right (слева-направо), как в английском, то элементы выравниваются, начиная с левой стороны контейнера.

Three items lined up on the left

Однако, если задан режим записи right-to-left (справа-налево), как в арабском языке, то элементы будут выстраиваться с правой стороны контейнера.

Three items lined up from the right

В примере ниже свойству property задано значение rtl , которое изменяет порядок наших элементов. Вы можете удалить это свойство или изменить значение свойства justify-content , чтобы увидеть, как работает flexbox, когда отображение элементов начинается справа.

Выравнивание и гибкое-направление

Начальное положение элементов поменяется, если вы измените значение свойства flex-direction — например установите row-reverse вместо row .

В следующем примере заданы следующие свойства: flex-direction: row-reverse и justify-content: flex-end . В языках с параметром записи ltr все элементы будут отображаться с левой стороны. Попробуйте изменить свойство flex-direction: row-reverse на flex-direction: row . Вы увидите, что теперь элементы отображаются реверсивно.

Может показаться немного запутанным, но главное правило, которое необходимо запомнить – до тех пор, пока вы не измените свойство flex-direction , элементы контейнера выстраиваются в режиме записи вашего языка ( ltr или rtl ).

Diagram showing start on the left and end on the right.

Вы можете сделать отображение элементов контейнера блочным, задав свойству flex-direction значение column . Свойство flex-start будет отображать элементы в столбец сверху вниз. Таким образом, первый элемент будет первым параграфом.

Diagram showing start at the top and end at the bottom.

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

Diagram showing start on the right and end on the left.

Diagram showing end at the top and start at the bottom

Использование авто отступов для выравнивания по главной оси

Так как элементы, расположенные на главной оси, обрабатываются как группа, свойства justify-items или justify-self становятся недоступными. Тем не менее, существует способ отделить конкретный элемент или группу элементов от остальных, используя внешний отступ margin со значением auto .

Распространённый пример — панель навигации, в которой отдельные важные элементы выровнены по правому краю, а основная группа элементов — по левому.

На первый взгляд может показаться, что этот пример использования свойства justify-self . Однако, рассмотрим следующий ниже пример. Имеется три элемента с одной стороны и два — с другой. Если бы мы могли использовать justify-self на элементе d, это также изменило бы выравнивание следующего элемента — e, что может противоречить первоначальному замыслу.

Five items, in two groups. Three on the left and two on the right.

Вместо этого мы можем выбрать четвёртый элемент (d) и отделить его от первых трёх, задав ему значение auto для margin-left . Авто-margin заполнит всё доступное свободное место по своей оси. Тем же образом работает margin-right . Оба свойства со значениями auto отцентрируют блок, так как каждый из отступов будет пытаться занять максимум пространства.

В интерактивном примере ниже у нас имеется простой ряд из флекс-элементов и класс push с заданным margin-left: auto . Вы можете, например, попробовать удалить это значение или добавить класс другому элементу, чтобы увидеть, как работает этот метод.

Будущие функции выравнивания для Flexbox

В начале этой статьи объясняется, что свойства выравнивания, которые в настоящее время содержатся в спецификации Flexbox Level 1, также включены в спецификацию Box Alignment Level 3, которая в дальнейшем может расширить эти свойства и значения. Мы уже видели, как это произошло с введением значения space-evenly для свойств align-content и justify-content .

Выравнивание во Flexbox также включает в себя другие методы создания пространства между элементами, такие как column-gap and row-gap , как показано в макете CSS Grid Layout. Включение этих свойств в Box Alignment означает, что в будущем мы также сможем использовать column-gap и row-gap во Flexbox разметке. Это означает, что вам не нужно будет использовать отступы, чтобы создать пространство между элементами.

Моё предложение заключается в том, чтобы при изучении выравнивания во Flexbox, делать это параллельно с выравниванием в Grid Layout. В обеих спецификациях используются свойства выравнивания, подобные Flexbox. Вы можете видеть, как эти свойства ведут себя при работе с сеткой в статье Box Alignment in Grid Layout, а также рассмотреть как выравнивание работает в этих спецификациях в статье Box Alignment Cheatsheet.

Читайте также: