Как работает flex-wrap с align-self, align-items и align-content?

align-self

в следующем коде align-self работает с flex-wrap: nowrap.

enter image description here

flex-container {
  display: flex;
  flex-wrap: nowrap;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
flex-item:last-child {
  align-self: flex-end;
  background-color: crimson;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

но когда контейнер переключается на flex-wrap: wrap, the align-self собственность не получается.

enter image description here

flex-container {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
flex-item:last-child {
  align-self: flex-end;
  background-color: crimson;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

align-items

аналогично, почему align-items работа здесь (wrap disabled):

enter image description here

flex-container {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

...но не здесь (wrap включен):

enter image description here

flex-container {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}

flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

align-content

С flex-wrap: nowrap на align-content свойство не будет вертикально центрировать элементы flex здесь:

enter image description here

flex-container {
  display: flex;
  flex-wrap: nowrap;
  align-content: center;
  width: 250px;
  height: 250px;
  background-color: silver;
}

flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

но тогда, как ни странно, если wrap включен и align-content остается, контейнер создает широкие промежутки между строками здесь:

enter image description here

flex-container {
  display: flex;
  flex-wrap: wrap;
  /* align-content: center; */
  width: 250px;
  height: 250px;
  background-color: silver;
}

flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

и align-self строительство снова.

enter image description here

flex-container {
  display: flex;
  flex-wrap: wrap;
  /* align-content: center; */
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}

flex-item:nth-child(even) {
  align-self: flex-end;
  background-color: crimson;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

как flex-wrap работы с align-self, align-items и align-content?

2 ответов


Короткий Ответ:

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

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

  • flex-wrap: nowrap создает один-линия Flex-контейнер
  • flex-wrap: wrap и wrap-reverse создать мульти-линия Flex-контейнер

на align-items и align-self свойства работают как в однострочных, так и в многострочных контейнерах. Однако они могут иметь эффект только тогда, когда есть свободное пространство в поперечной оси гибкой линии.

на align-content свойство работает только в многострочных контейнеров. Он игнорируется в однострочных контейнерах.


объяснение

на адаптируемых блоков спецификация предоставляет четыре свойства ключевых слов для выравнивания элементов flex:

  • align-items
  • align-self
  • align-content
  • justify-content

чтобы понять функции этих свойств важно сначала понять структуру контейнера Flex.


Часть 1: понимание главной оси и поперечной оси гибкого трубопровода Контейнер

оси X и Y

гибкий контейнер работает в двух направлениях: ось x (горизонтальная) и ось y (вертикальная).

x-axis and the y-axis

источник: Википедия

дочерние элементы контейнера flex – известный как" flex items " – может быть выровнен в любом направлении.

это Flex выравнивание на самом фундаментальном уровне.

главная и поперечная оси

наложение осей x и y, в компоновке flex,main и крест топоры.

по умолчанию основная ось горизонтальна (ось x), а поперечная ось вертикальна (ось y). Это начальная настройка, как определяется спецификация flexbox.

flex main axis and cross axis

источник: W3C по

однако, в отличие от осей x и y, которые фиксированы, основные и поперечные оси могут переключаться в направлениях.

на flex-direction Собственность

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

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

спецификации:

5.1. Направление подачи гибкого трубопровода:flex-direction собственность

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

есть четыре значения для flex-direction свойства:

/* main axis is horizontal, cross axis is vertical */
flex-direction: row; /* default */
flex-direction: row-reverse;

/* main axis is vertical, cross axis is horizontal */    
flex-direction: column;
flex-direction: column-reverse;

поперечная ось всегда перпендикулярна главная ось.


Часть 2: Гибкие Линии

внутри контейнера элементы flex существуют в строке, известной как"линия flex".

линия гибкого трубопровода строка или столбец, в зависимости от flex-direction.

контейнер может иметь одну или более строк, в зависимости от flex-wrap.

Один-Линия Flex-Контейнер

flex-wrap: nowrap устанавливает единый-линия Flex-контейнер, в который Flex элементы вынуждены оставаться в одной строке (даже если они переполнения контейнера).

a single-line flex container (one column)

изображение выше имеет одну гибкую линию.

flex-container {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap; /* <-- allows single-line flex container */
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  width: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

Мульти-Линия Flex-Контейнер

flex-wrap: wrap или wrap-reverse устанавливает многострочный контейнер flex, в котором элементы flex могут создавать новые русло.

multi-line flex container (3 columns)

изображение выше, имеет три гибких линий.

flex-container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap; /* <-- allows multi-line flex container */
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  width: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

multi-line flex container (3 rows)

изображение выше, имеет три гибких линий.

flex-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap; /* <-- allows multi-line flex container */
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

Часть 3: Свойства Выравнивания Ключевых Слов

свойства Присваивается главной и поперечной (не X и Y) осям

с flex-direction свойство управляет направлением, в котором элементы flex выложены, есть четыре свойства, которые управляют выравниванием и позиционированием. Это:

  • align-items
  • align-self
  • align-content
  • justify-content

каждое из этих свойств постоянно присваивается ось.

на justify-content свойство работает только на главной оси.

трех align-* свойства работают только на поперечной оси.

обычно ошибочно полагать, что эти свойства фиксированы к осям x и Y. Например, justify-content всегда горизонтально, и align-items всегда вертикальна.

, когда flex-direction переходит в column главная ось становится осью Y и justify-content строительство вертикально.

фокус этого поста выравнивание поперечной оси. Для объяснения выравнивания главной оси и justify-content свойство, см. Этот пост:

определения

спецификация flexbox предоставляет три свойства ключевых слов для кросс-оси выравнивание:

  • align-items
  • align-self
  • align-content

align-items / align-self

на align-items свойства выравнивает элементов контейнера вдоль оси пересечения линии Flex. Он распространяется на контейнеры Flex.

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

вот определение из spec:

8.3. Выравнивание поперечной оси:align-items и align-self свойства

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

существует шесть возможных значений для align-items / align-self:

  • flex-start
  • flex-end
  • center
  • baseline
  • stretch
  • auto (align-self только)

(для описания каждого значения нажмите на заголовок определения спецификации выше.)

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

начальное значение align-self is auto, т. е. он наследует значение align-items.

Ниже приведена иллюстрация влияния каждого значения в контейнере направления строки.

align-items align-self values

источник: W3C по

align-content

это свойство немного сложнее, чем align-items и align-self.

вот определение из спецификации:

8.4. Упаковка гибкий строки:align-content собственность

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

в отличие от align-items и align-self, которые перемещают элементы flex в пределах их линии, align-content перемещение гибких линий в контейнере.

существует шесть возможных значений для align-content:

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • stretch

(для описания каждого значения нажмите на заголовок определения спецификации выше.)

Ниже приведена иллюстрация влияния каждого значения в направлении строки контейнер.

enter image description here

источник: W3C по

почему align-content работа только в Multi-line контейнерах гибкого трубопровода?

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

здесь соответствующий раздел спецификации:

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


Часть 4: Примеры Объяснены

enter image description here

В Примере #1, align-self работает с flex-wrap: nowrap потому что элементы flex существуют в однострочном контейнере. Поэтому, одна линия гибкого трубопровода и она соответствует высоте контейнера.

flex-container {
  display: flex;
  flex-wrap: nowrap;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
flex-item:last-child {
  align-self: flex-end;
  background-color: crimson;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

enter image description here

В Примере № 2 align-self не потому, что он существует в многострочном контейнере (flex-wrap: wrap) и align-content установлено значение flex-start. Это значит что линии гибкого трубопровода упакованы плотно к началу перекрестной оси, не выходя никакой Свободный космос для align-self на работу.

flex-container {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
flex-item:last-child {
  align-self: flex-end;
  background-color: crimson;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

enter image description here

объяснение для примера #3 такое же, как, например #1.

flex-container {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

enter image description here

объяснение для примера #4 такое же, как и для примера #2.

flex-container {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}

flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

enter image description here

Пример #5-однолинейная контейнер. Таким образом, поперечный размер гибкой линии равен поперечному размеру контейнера, не оставляя дополнительного пространства между ними. Следовательно,align-content, который выравнивает гибкие линии когда есть дополнительное пространство в поперечной оси, имеет никакого эффекта.

flex-container {
  display: flex;
  flex-wrap: nowrap;
  align-content: center;
  width: 250px;
  height: 250px;
  background-color: silver;
}

flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

enter image description here

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

это распределение пространства между строками может привести к большим зазорам между строками / столбцами. Чем меньше линий, тем больше разрывов. Больше линий приводят к меньшим промежуткам, так как каждая линия получает меньшую долю пространства.

для решения этой проблемы переключитесь с align-content: stretch to align-content: flex-start. Этого набора строк (см. примеры № 2 и № 4 выше). Конечно, это также исключает любое свободное пространство в строке, и align-items и align-self больше не могу работа.

вот по теме: удалить пространство (зазоры) между несколькими линиями гибких элементов, когда они обернуть

flex-container {
  display: flex;
  flex-wrap: wrap;
  /* align-content: center; */
  width: 250px;
  height: 250px;
  background-color: silver;
}

flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

enter image description here

как описано в предыдущих примерах, с align-content: stretch, может быть дополнительное пространство в гибких линиях, что позволяет align-items и align-self на работу. Любое другое значение для align-content упаковало бы линии, исключающ экстренный космос, и делающ align-items и align-self бесполезно.

flex-container {
  display: flex;
  flex-wrap: wrap;
  /* align-content: center; */
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}

flex-item:nth-child(even) {
  align-self: flex-end;
  background-color: crimson;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

прежде всего, align-content бесполезен, если нет обертки:

W3C в док

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

кроме того, во втором случае выровняйте себя не. Это бесполезно, потому что внутренние линии упакованы. Давайте создадим пространство, чтобы стиль мог работать:

flex-container {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}
flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
flex-item:last-child {
  align-self: flex-end;
  background-color: crimson;
}
flex-item:nth-child(5) {
  height: 90px;  /* added */
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

аналогично, в вашем 4-м примере стиль работает, если вы установите условия, в которых его можно увидеть

flex-container {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  align-content: flex-start;
  width: 250px;
  height: 250px;
  background-color: silver;
}

flex-item {
  flex: 0 0 50px;
  height: 50px;
  margin: 5px;
  background-color: lightgreen;
}
flex-item:nth-child(2),flex-item:nth-child(5) {
  height: 90px;  /* added */
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

наконец, когда вы комментируете align-content, он возвращается к стрейч, вот почему линии увеличивают размер, чтобы заполнить контейнер

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