Основные понятия гибкой компоновки
Модуль гибкой компоновки (обычно называемый flexbox) — это одномерная модель компоновки для распределения пространства между элементами и включает множество возможностей выравнивания. Эта статья предоставляет обзор основных функций flexbox, которые мы более подробно рассмотрим в последующих руководствах.
Когда мы описываем flexbox как одномерную модель, мы имеем в виду, что flexbox обрабатывает компоновку в одном измерении за раз — либо как строку, либо как столбец. Это можно противопоставить двумерной модели CSS Grid Layout, которая управляет столбцами и строками вместе.
Две оси flexbox
Работая с flexbox, вам необходимо работать с двумя осями — осью направления и осью пересечения. Ось направления определяется свойством flex-direction, а ось пересечения перпендикулярна ей. Все, что мы делаем с flexbox, относится к этим осям, поэтому стоит понять, как они работают с самого начала.
Ось направления
Ось направления определяется свойством flex-direction, которое имеет четыре возможных значения:
rowrow-reversecolumncolumn-reverse
Если вы выберете row или row-reverse, ваша ось направления будет проходить по строке в горизонтальном направлении.
Выбрав column или column-reverse, ваша ось направления будет идти в вертикальном направлении, сверху вниз страницы.
Ось пересечения
Ось пересечения перпендикулярна оси направления. Поэтому, если ваша ось направления (ось направления) установлена в flex-direction или row значение, ось пересечения идёт по столбцам.
Если ваша ось направления установлена в column или column-reverse, тогда ось пересечения идёт по строкам.
Начальная и конечная линии
Еще один важный аспект — то, как flexbox не делает предположений о режиме написания документа. Flexbox не предполагает, что все строки текста начинаются в верхнем левом углу документа и идут вправо, а новые строки появляются одна под другой. Вместо этого он поддерживает все режимы написания, как и другие логические свойства и значения.
Вы можете подробнее узнать об отношениях между flexbox и режимами написания в последующих статьях, однако следующее описание поможет объяснить, почему мы не говорим о левом и правом, верхнем и нижнем, когда описываем направление потока flex-элементов.
Если ось направления flex-direction имеет значение row, а я работаю в английском языке, то начальная граница оси направления будет слева, а конечная — справа.
Если бы я работал с арабским языком, то начальная граница моей оси направления была бы справа, а конечная — слева.
В обоих случаях начальная граница оси пересечения находится вверху flex-контейнера, а конечная — внизу, так как оба языка имеют горизонтальный режим написания.
Со временем привыкание к начальной и конечной границам вместо левой и правой станет естественным и полезным при работе с другими методами компоновки, такими как CSS Grid Layout, которые следуют тем же паттернам.
Контейнер flex
Область документа, которая выстраивается с помощью flexbox, называется flex-контейнером. Чтобы создать flex-контейнер, установите свойство области display в значение flex. При этом прямые дочерние элементы этого контейнера становятся flex-элементами. Вы можете явно контролировать, отображается ли сам контейнер в формате строки или в формате блока, используя inline flex или inline-flex для контейнеров inline flex или block flex или flex для контейнеров block flex.
Начальные значения
Как и все свойства в CSS, некоторые начальные значения определены, поэтому содержимое нового flex-контейнера будет вести себя следующим образом:
- Элементы отображаются в строке (по умолчанию для свойства
flex-directionзначениеrow). - Элементы начинаются с начальной границы оси направления.
- Элементы не растягиваются по размеру оси направления, но могут сжиматься (по умолчанию для свойства flex-элемента
flex-growзначение0, а для свойстваflex-shrink— значение1). - Элементы будут растягиваться для заполнения размера оси пересечения (по умолчанию для свойства
align-itemsзначениеstretch). - Значение свойства flex-элемента
flex-basisпо умолчаниюauto. Это означает, что в каждом случае оно будет равно ширине flex-элементаwidthв горизонтальном режиме написания и высоте flex-элементаheightв вертикальном режиме написания. Если соответствующее свойствоwidth/heightтакже установлено вauto, вместо этого используется значениеflex-basiscontent. - Все элементы будут в одной строке (по умолчанию для свойства
flex-wrapзначениеnowrap), выходя за пределы своего контейнера, если их суммарные размерыwidth/heightпревышают размер контейнераwidth/height.
Результат заключается в том, что все ваши элементы выстраиваются в строку, используя размер содержимого в качестве своего размера по оси направления. Если элементов больше, чем помещается в контейнер, они не будут переносить, а вместо этого выйдут за его пределы. Если некоторые элементы выше других, все элементы будут растянуты на всю длину оси пересечения.
Вы можете увидеть, как это выглядит в примере ниже. Нажмите «Играть», чтобы открыть пример в MDN Playground и изменить элементы или добавить новые, чтобы попробовать начальное поведение flexbox:
<div class="box"> <div>One</div> <div>Two</div> <div>Three <br />has <br />extra <br />text</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
}
Изменение flex-direction
Добавление свойства flex-direction к flex-контейнеру позволяет изменить направление отображения flex-элементов. Установка значения flex-direction: row-reverse сохранит отображение элементов по горизонтали, но начальные и конечные линии будут переставлены.
Если мы изменим flex-direction на column, ось направления поменяется, и наши элементы теперь будут отображаться в столбце. Установка column-reverse снова переставит начальные и конечные линии.
В примере ниже свойство flex-direction установлено в row-reverse. Попробуйте другие значения — row, column и column-reverse, чтобы увидеть, что произойдёт с содержимым.
<div class="box"> <div>One</div> <div>Two</div> <div>Three</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
flex-direction: row-reverse;
}
Многострочные flex-контейнеры с flex-wrap
Хотя flexbox — это одномерная модель, можно сделать flex-элементы, которые переносятся на несколько строк. В этом случае каждую строку следует рассматривать как новый flex-контейнер. Распределение пространства будет происходить в каждой строке, без ссылки на предыдущие или последующие строки.
Чтобы включить перенос, добавьте свойство flex-wrap со значением wrap. Теперь, если ваши элементы слишком велики для отображения в одной строке, они будут переноситься на другую строку. В примере ниже элементы имеют width. Общая ширина элементов слишком велика для flex-контейнера. Так как flex-wrap установлено в wrap, элементы переносятся на несколько строк. Если вы установите его в nowrap, которое является начальным значением, элементы будут уменьшены, чтобы поместиться в контейнер. Они уменьшаются, потому что используют начальные значения flexbox, в том числе flex-shrink: 1, что позволяет элементам сжиматься. Использование nowrap вызвало бы переполнение, если элементы не смогли бы сжаться или не смогли бы сжаться достаточно сильно, чтобы поместиться.
<div class="box"> <div>One</div> <div>Two</div> <div>Three</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
width: 200px;
}
.box {
width: 500px;
border: 2px dotted rgb(96 139 168);
display: flex;
flex-wrap: wrap;
}
Дополнительную информацию о переносе flex-элементов вы найдёте в руководстве Освоение переноса flex-элементов.
Сокращенное свойство flex-flow
Вы можете объединить два свойства flex-direction и flex-wrap в сокращенное свойство flex-flow.
В примере ниже попробуйте изменить первое значение на одно из допустимых значений для flex-direction — row, row-reverse, column или column-reverse, а также измените второе значение на wrap и nowrap.
<div class="box"> <div>One</div> <div>Two</div> <div>Three</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
width: 200px;
}
.box {
width: 500px;
border: 2px dotted rgb(96 139 168);
display: flex;
flex-flow: row wrap;
}
Свойства, применяемые к элементам flex
Для управления размером каждого элемента flex мы напрямую используем три свойства:
Мы кратко рассмотрим эти свойства ниже, но если вам нужна более подробная информация, обратитесь к руководству Контроль соотношений элементов flex на основной оси.
Прежде чем мы сможем разобраться с этими свойствами, нам нужно рассмотреть понятие доступного пространства. То, что мы делаем, изменяя значение этих свойств flex, заключается в изменении способа распределения доступного пространства между нашими элементами. Это понятие доступного пространства также важно, когда дело доходит до выравнивания элементов.
Если у нас есть три элемента шириной 100 пикселей в контейнере шириной 500 пикселей, то пространство, необходимое для размещения наших элементов, составляет 300 пикселей. Это оставляет 200 пикселей доступного пространства. Если мы не изменим начальные значения, то flexbox разместит это пространство после последнего элемента.
Если вместо этого мы хотим, чтобы элементы увеличивались и заполняли все пространство, нам нужен способ распределения оставшегося пространства между элементами. Свойства flex , которые мы применяем к самим элементам, позволяют указать, как это доступное пространство должно распределяться между соседними элементами flex.
Свойство flex-basis
Свойство flex-basis определяет размер элемента в отношении пространства, которое остается в качестве доступного. Начальное значение этого свойства составляет auto — в этом случае браузер проверяет, есть ли у элемента размер. В приведенном выше примере все элементы имеют ширину 100 пикселей. Это используется как flex-basis.
Если у элементов нет размера, то размер содержимого используется в качестве flex-basis. Именно поэтому, когда мы просто объявляем display: flex на родительском элементе, чтобы создать элементы flex, все элементы перемещаются в строку и занимают только столько места, сколько им необходимо для отображения своего содержимого.
Свойство flex-grow
Если свойство flex-grow установлено в положительное целое число, то, если есть доступное пространство, элемент flex может увеличиваться вдоль основной оси от своего flex-basis. Будет ли элемент растягиваться, чтобы занять все доступное пространство на этой оси, или только часть доступного пространства, зависит от того, разрешено ли другим элементам расти также и от значения их свойств flex-grow.
Каждый элемент с положительным значением потребляет часть любого доступного пространства, основываясь на их значении flex-grow. Если мы установили всем элементам в примере выше значение flex-grow равное 1, то доступное пространство в контейнере flex будет разделено поровну между нашими элементами, и они растянутся, чтобы заполнить контейнер по основной оси. Если мы дадим первому элементу значение flex-grow равное 2, а другим элементам значение 1 каждое, то всего будет 4 части; 2 части доступного пространства будут переданы первому элементу (100 пикселей из 200 пикселей в случае примера выше), и по 1 части каждой из двух других (50 пикселей каждая из 200 пикселей в сумме).
Свойство flex-shrink
Если свойство flex-grow отвечает за добавление пространства на основной оси, то свойство flex-shrink управляет тем, как это пространство отнимается. Если у нас недостаточно места в контейнере для размещения наших элементов, и flex-shrink установлено в положительное целое число, то элемент может стать меньше, чем flex-basis. Как и в случае со свойством flex-grow, можно назначить различные значения, чтобы заставить один элемент уменьшаться быстрее, чем другие — элемент с более высоким значением flex-shrink будет уменьшаться быстрее, чем его аналоги с меньшими значениями.
Элемент может уменьшиться до своего размера min-content. Этот минимальный размер учитывается при расчете фактического количества уменьшения, что означает, что flex-shrink может вести себя менее последовательно, чем flex-grow. Поэтому мы подробнее рассмотрим, как работает этот алгоритм, в статье Контроль соотношений элементов по основной оси.
Примечание: Эти значения для flex-grow и flex-shrink являются пропорциями. Обычно, если мы установили всем элементам значение flex: 1 1 200px, а затем хотим, чтобы один элемент рос в два раза быстрее, мы установили бы для этого элемента значение flex: 2 1 200px. Однако можно также использовать значения flex: 10 1 200px и flex: 20 1 200px.
Сокращенные значения для свойств flex
Вы очень редко увидите свойства flex-grow, flex-shrink, и flex-basis используемыми по отдельности; вместо этого они объединены в сокращенное свойство flex. Сокращенное свойство flex позволяет задать три значения в этом порядке — flex-grow, flex-shrink, flex-basis.
В приведенном ниже примере можно проверить различные значения сокращенного свойства flex; помните, что первое значение — flex-grow. Присвоение положительного значения означает, что элемент может расти. Второе — flex-shrink — положительное значение позволяет элементам сжиматься, но только если их суммарные значения выходят за пределы основной оси. Последнее значение — flex-basis; это значение, которое элементы используют в качестве базового значения для роста и уменьшения.
<div class="box"> <div class="one">One</div> <div class="two">Two</div> <div class="three">Three</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
}
.one {
flex: 1 1 auto;
}
.two {
flex: 1 1 auto;
}
.three {
flex: 1 1 auto;
}
Существуют также некоторые предопределенные сокращенные значения, которые охватывают большинство случаев использования. Вы часто будете видеть их в руководствах, и во многих случаях их будет достаточно. Предопределенные значения следующие:
flex: initialflex: autoflex: noneflex: <positive-number>
Значение initial — это CSS-значение, которое представляет собой начальное значение свойства. Установка flex: initial сбрасывает элемент до начальных значений для трех свойств, что эквивалентно flex: 0 1 auto. Начальное значение flex-grow — 0, поэтому элементы не будут увеличиваться больше, чем их размер flex-basis. Начальное значение flex-shrink — 1, поэтому элементы могут уменьшаться, если это необходимо, а не переполнять. Начальное значение flex-basis — auto. Элементы будут использовать любой размер, установленный для элемента в главном измерении, или получат свой размер из размера содержимого.
Использование flex: auto эквивалентно использованию flex: 1 1 auto; это аналогично flex: initial, за исключением того, что элементы могут расти и заполнять контейнер, а также уменьшаться при необходимости.
Использование flex: none создаст полностью негибкие элементы flex. Это так, как если бы вы написали flex: 0 0 auto. Элементы не могут расти или уменьшаться и будут размещаться с помощью flexbox с значением flex-basis равным auto.
Сокращенное значение, которое часто используется в руководствах, — flex: 1 или flex: 2 и так далее. Это то же самое, что и написание flex: 1 1 0 или flex: 2 1 0 и так далее, соответственно. Элементы могут расти и уменьшаться от значения flex-basis равного 0.
Попробуйте эти сокращенные значения в приведенном ниже примере.
<div class="box"> <div class="one">One</div> <div class="two">Two</div> <div class="three">Three</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
}
.one {
flex: 1;
}
.two {
flex: 1;
}
.three {
flex: 1;
}
Выравнивание, выравнивание по границам и распределение свободного пространства между элементами
Ключевой особенностью flexbox является возможность выравнивания и выравнивания по границам элементов по основным и поперечным осям, а также распределение пространства между элементами flex. Обратите внимание, что эти свойства устанавливаются для контейнера flex, а не для самих элементов.
align-items
Свойство align-items выравнивает все элементы flex по поперечной оси.
Начальное значение этого свойства — stretch, поэтому элементы flex по умолчанию растягиваются до высоты контейнера flex (или ширины, если flex-direction установлено на column или column-reverse). Эта высота может быть равна высоте самого высокого элемента в контейнере или размеру, заданному в самом контейнере flex.
Вместо этого вы можете установить align-items на flex-start, или просто start, чтобы выровнять элементы в начале контейнера flex, flex-end, или end, чтобы выровнять их в конце, или center, чтобы выровнять их по центру. Попробуйте это в интерактивном примере — я задал высоту контейнера flex, чтобы вы могли увидеть, как элементы можно перемещать внутри него. Посмотрите, что произойдёт, если вы зададите значение align-items:
stretchflex-startflex-endstartendcenterbaselinelast baseline
<div class="box"> <div>One</div> <div>Two</div> <div>Three <br />has <br />extra <br />text</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.box {
width: 500px;
height: 130px;
border: 2px dotted rgb(96 139 168);
display: flex;
align-items: flex-start;
}
Свойство align-items устанавливается в контейнере flex и влияет на все элементы flex. Если вам нужно выровнять элемент flex иначе, чем другие, вы можете установить align-self для этого элемента.
justify-content
Свойство justify-content используется для выравнивания элементов по главной оси, направлению, в котором flex-direction задаёт поток. Начальное значение — flex-start, что выравнивает элементы по начальному краю контейнера, но вы также можете установить значение на flex-end, чтобы выровнять их по конечному краю, или center, чтобы выровнять их по центру.
Вы также можете использовать значение space-between, чтобы заполнить всё свободное пространство после размещения элементов и равномерно распределить его между ними, обеспечив одинаковое расстояние между каждым элементом. Чтобы обеспечить одинаковое расстояние справа и слева (или сверху и снизу для столбцов) от каждого элемента, используйте значение space-around. Со значением space-around элементы имеют расстояние размером в половину, по обеим сторонам. Или, чтобы создать одинаковое расстояние вокруг элементов, используйте значение space-evenly. Со значением space-evenly элементы имеют расстояние размером в целое, по обеим сторонам.
Попробуйте следующие значения justify-content в интерактивном примере:
startendleftrightnormalflex-startflex-endcenterspace-aroundspace-betweenspace-evenlystretch
<div class="box"> <div>One</div> <div>Two</div> <div>Three</div> </div>
.box > * {
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
justify-content: flex-start;
}
Статья Выравнивание элементов в контейнере flex более подробно изучает эти свойства, чтобы лучше понять их работу. Однако эти базовые примеры полезны в большинстве случаев.
justify-items
Свойство justify-items игнорируется в макетах flexbox.
place-items и place-content
Свойство place-items — это сокращённое свойство для align-items и justify-items. Если оно установлено в контейнере flex, оно установит выравнивание, но не выравнивание по границам, и justify-items игнорируется в flexbox.
Существует ещё одно сокращённое свойство, place-content, которое определяет свойства align-content и justify-content. Свойство align-content влияет только на контейнеры flex, которые перестраиваются, и обсуждается в статье Выравнивание элементов в контейнере flex.
Следующие шаги
После прочтения этой статьи у вас должно быть понимание основных функций flexbox. В следующей статье мы рассмотрим как эта спецификация относится к другим частям CSS.
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox