Способы выравнивания гибких элементов по главной оси
Как указано в вопросе:
Для выравнивания гибких элементов по главной оси есть одно свойство: justify-content
Для выравнивания гибких элементов по поперечной оси есть три свойства: align-content
, align-items
и align-self
<22670212670212>.
Затем задается вопрос:
Почему отсутствуют свойства justify-items
и justify-self
?
Один ответ может быть: Потому что они не нужны.
Спецификация flexbox предоставляет два метода для выравнивания гибких элементов вдоль главной оси:
- свойство ключевого слова
justify-content
и
-
auto
поля
justify-content
Свойство justify-content
выравнивает гибкие элементы вдоль главной оси гибкого контейнера.
Он применяется к гибкому контейнеру, но влияет только на гибкие элементы.
Есть пять вариантов выравнивания:
-
flex-start
~ Элементы Flex упаковываются в начало строки.
-
flex-end
~ Элементы Flex упаковываются ближе к концу строки.
-
center
~ Элементы Flex упаковываются к центру линии.
-
space-between
~ Элементы Flex расположены равномерно: первый элемент выровнен по одному краю контейнера, а последний элемент - по противоположному краю. Края, используемые первым и последним элементами, зависят от flex-direction
и режима записи (ltr
или rtl
).
-
space-around
~ То же, что и space-between
, за исключением пробелов половинного размера на обоих концах.
Автоматические поля
С auto
полями гибкие элементы можно центрировать, разносить или упаковывать в подгруппы.
В отличие от justify-content
, который применяется к гибкому контейнеру, auto
поля идут на гибких элементах.
Они работают, занимая все свободное пространство в указанном направлении.
Выровнять группу гибких элементов вправо, но первый элемент слева
Сценарий из вопроса:
-
выравнивание группы гибких элементов по правому краю (justify-content: flex-end
)
но выровняйте первый элемент по левому краю (justify-self: flex-start
)
Рассмотрим раздел заголовка с группой элементов навигации и логотипом. С участием
justify-self
логотип можно было выровнять по левому краю, а элементы навигации остались.
крайний правый, и все это плавно подстраивается ("изгибается") до
разные размеры экрана.
Другие полезные сценарии:
Поместите гибкий элемент в угол
Сценарий из вопроса:
- размещение гибкого элемента в углу
.box { align-self: flex-end; justify-self: flex-end; }
Центрировать гибкий элемент по вертикали и горизонтали
margin: auto
является альтернативой justify-content: center
и align-items: center
.
Вместо этого кода на гибком контейнере:
.container {
justify-content: center;
align-items: center;
}
Вы можете использовать это на гибком элементе:
.box56 {
margin: auto;
}
Эта альтернатива полезна, когда центрирует гибкий элемент, который выходит за пределы контейнера .
Центрировать гибкий элемент и центрировать второй гибкий элемент между первым и краем
Гибкий контейнер выравнивает гибкие элементы, распределяя свободное пространство.
Следовательно, для создания равного баланса , чтобы средний элемент можно было центрировать в контейнере с одним элементом рядом, необходимо ввести противовес.
В приведенных ниже примерах невидимые третьи гибкие элементы (поля 61 и 68) представлены для уравновешивания «реальных» элементов (поля 63 и 66).
Конечно, в этом методе нет ничего особенного с точки зрения семантики.
В качестве альтернативы вы можете использовать псевдоэлемент вместо фактического элемента DOM. Или вы можете использовать абсолютное позиционирование. Здесь описаны все три метода: Гибкие элементы с выравниванием по центру и снизу
ПРИМЕЧАНИЕ. Приведенные выше примеры будут работать - с точки зрения истинного центрирования - только когда крайние элементы равны по высоте / ширине. Если гибкие элементы имеют разную длину, см. Следующий пример.
Центрировать гибкий элемент, когда соседние элементы различаются по размеру
Сценарий из вопроса:
-
в ряду из трех гибких элементов прикрепите средний элемент к центру контейнера (justify-content: center
) и выровняйте соседние
элементы к краям контейнера (justify-self: flex-start
и
justify-self: flex-end
).
Обратите внимание, что значения space-around
и space-between
в свойстве justify-content
не будут удерживать средний элемент по центру по отношению к контейнеру, если соседние элементы имеют разную ширину (см. Демонстрацию12158226702) .
Как уже отмечалось, если все гибкие элементы не имеют одинаковой ширины или высоты (в зависимости от flex-direction
), средний элемент не может быть полностью центрирован. Эта проблема является убедительным аргументом в пользу свойства justify-self
(разумеется, предназначенного для решения этой задачи).
#container {
display: flex;
justify-content: space-between;
background-color: lightyellow;
}
.box {
height: 50px;
width: 75px;
background-color: springgreen;
}
.box1 {
width: 100px;
}
.box3 {
width: 200px;
}
#center {
text-align: center;
margin-bottom: 5px;
}
#center > span {
background-color: aqua;
padding: 2px;
}
<div id="center">
<span>TRUE CENTER</span>
</div>
<div id="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
<p>The middle box will be truly centered only if adjacent boxes are equal width.</p>
Вот два метода решения этой проблемы:
Решение №1: Абсолютное позиционирование
Спецификация flexbox допускает абсолютное позиционирование гибких элементов. Это позволяет идеально центрировать средний элемент независимо от размера его братьев и сестер.
Просто имейте в виду, что, как и все элементы с абсолютным позиционированием, эти элементы удаляются из потока документов . Это означает, что они не занимают места в контейнере и могут перекрывать своих братьев и сестер.
В примерах ниже средний элемент центрируется с абсолютным позиционированием, а внешние элементы остаются в потоке. Но такая же компоновка может быть получена и в обратном порядке: центрировать средний элемент с помощью justify-content: center
и абсолютно позиционировать внешние элементы.
Решение №2: вложенные гибкие контейнеры (без абсолютного позиционирования)
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box71 > span { margin-right: auto; }
.box73 > span { margin-left: auto; }
/* non-essential */
.box {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
<div class="container">
<div class="box box71"><span>71 short</span></div>
<div class="box box72"><span>72 centered</span></div>
<div class="box box73"><span>73 loooooooooooooooong</span></div>
</div>
Вот как это работает:
- Div верхнего уровня (
.container
) - это гибкий контейнер.
- Каждый дочерний div (
.box
) теперь является гибким элементом.
- Каждому элементу
.box
дается flex: 1
для равномерного распределения пространства контейнера.
- Теперь элементы занимают все пространство в строке и имеют одинаковую ширину.
- Сделайте каждый элемент (вложенным) гибким контейнером и добавьте
justify-content: center
.
- Теперь каждый элемент
span
представляет собой центрированный гибкий элемент.
- Используйте гибкие поля
auto
для смещения внешних span
влево и вправо.
Вы также можете отказаться от justify-content
и использовать исключительно поля auto
.
Но justify-content
может работать здесь, потому что поля auto
всегда имеют приоритет. Из спецификации:
8.1. Выравнивание с auto
поля
Перед выравниванием через justify-content
и align-self
любой
положительное свободное пространство распределяется по автоматическим полям в этом измерении.
justify-content: space-same (concept)
Вернемся на минутку к justify-content, вот идея для еще одного варианта.
-
space-same
~ Гибрид space-between
и space-around
. Элементы Flex расположены равномерно (например, space-between
), за исключением того, что вместо промежутков половинного размера на обоих концах (например, space-around
) на обоих концах есть полноразмерные промежутки.
Такой макет может быть достигнут с помощью ::before
и ::after
псевдоэлементов на гибком контейнере.
(кредит: @oriol для кода и @crl для метки)
ОБНОВЛЕНИЕ: Браузеры начали внедрять space-evenly
, что обеспечивает вышеуказанное. Подробнее см. В этом сообщении: Равное пространство между элементами гибкости
PLAYGROUND (включает код для всех примеров выше)
Как вы ожидаете, что
justify-self
будет работать с гибким элементом? Предположим, у вас есть элементы a, b, c, d с дополнительным пространством для распределения вокруг них, а в гибком контейнере естьjustify-content: space-between
, поэтому они заканчиваются как | a b c d |. Что означало бы добавить, например,justify-self: center
или 'justify-self: flex-end` только на элемент' b '? Куда вы его ожидали? (Я вижу несколько демонстраций в одном из ответов здесь, но я не вижу четкого способа, как это будет работать в целом.)(В качестве альтернативы: предположим, что у нас есть
justify-content: flex-start
, поэтому элементы переполнены в начале, например | abcd |. Что вы ожидаете от этого, если вы поместитеjustify-self: [anything]
в элемент 'b' там?)@dholbert, вы писали: Как вы ожидаете, что
justify-self
будет работать для гибких элементов? Я бы сказал, не так уж и иначе, чем поляauto
уже работают на гибких элементах. Во втором примереjustify-self: flex-end
в элементе d переместит его на дальний край. Это само по себе было бы отличной функцией, которую уже могут делать поляauto
. Отправил ответ с демонстрацией.В основном я вижу здесь больше вариантов использования, и варианты использования великолепны, но сложность заключается в том, как втиснуть это в фактический способ, которым указаны
justify-content
иjustify-self
, поэтому что случаи с конфликтами (например, сценарии, о которых я спрашивал) четко и разумно определены. Как я отметил в своем ответе здесь,{justify|align}-self
касается выравнивания элементов внутри большего блока, размер которого не зависит от значения{justify|align}-self
- и на главной оси такого блока нет для гибкий элемент, который нужно выровнять.RE "ничем не отличается от автоматического поля" - я действительно спрашивал, как вы представляете, как
justify-self
иjustify-content
будут взаимодействовать в случаях, когда они конфликтуют (как в сценариях, которые я изложил). Автоматические поля просто не вообще взаимодействуют сjustify-content
- они крадут все упаковочное пространство до того, какjustify-content
получит возможность его использовать. Итак, автоматические поля на самом деле не являются хорошим аналогом того, как это будет работать.