В CSS Flexbox, почему нет свойств "justify-items" и "justify-self"?
Рассмотрим основную ось и поперечную ось гибкого контейнера:
Источник: W3C
Чтобы выровнять элементы flex вдоль основной оси, существует одно свойство:
Чтобы выровнять элементы гибкости вдоль поперечной оси, существует три свойства:
На изображении выше основная ось горизонтальная, а поперечная ось - вертикальная. Это направления по умолчанию для гибкого контейнера.
Однако эти направления могут быть легко взаимозаменяемы с помощью свойства flex-direction
.
/* main axis is horizontal, cross axis is vertical */
flex-direction: row;
flex-direction: row-reverse;
/* main axis is vertical, cross axis is horizontal */
flex-direction: column;
flex-direction: column-reverse;
(поперечная ось всегда перпендикулярна основной оси.)
Моя точка в описании работы осей заключается в том, что в любом направлении нет ничего особенного. Основная ось, поперечная ось, они оба равны по важности, а flex-direction
позволяет легко переключаться назад и вперед.
Так почему же поперечная ось получает два дополнительных свойства выравнивания?
Почему align-content
и align-items
объединены в одно свойство для главной оси?
Почему главная ось не получает свойство justify-self
?
Сценарии, в которых эти свойства были бы полезны:
-
размещение гибкого элемента в углу гибкого контейнера
#box3 { align-self: flex-end; justify-self: flex-end; }
-
создание группы элементов flex align-right (justify-content: flex-end
), но первый элемент выравнивается влево (justify-self: flex-start
)
Рассмотрим раздел заголовка с группой навигационных элементов и логотипом. С justify-self
логотип можно было бы выровнять влево, в то время как пункты навигации остаются правыми, и все это будет плавно ( "сгибать" ) на разные размеры экрана.
-
в строке из трех элементов гибкости привяжите средний элемент к центру контейнера (justify-content: center
) и выровняйте смежные элементы к краям контейнера (justify-self: flex-start
и justify-self: flex-end
).
Обратите внимание, что значения space-around
и space-between
on
justify-content
свойство не будет удерживать средний элемент по центру относительно контейнера, если соседние элементы имеют разную ширину.
#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>note that the middle box will only be truly centered if adjacent boxes are equal width</p>
Ответы
Ответ 1
Методы выравнивания изгибаемых элементов вдоль главной оси
Как указано в вопросе:
Для выравнивания элементов Flex по главной оси есть одно свойство: justify-content
Для выравнивания элементов Flex по поперечной оси есть три свойства: align-content
, align-items
и align-self
.
Затем возникает вопрос:
Почему нет justify-items
и justify-self
свойств?
Один ответ может быть: потому что они не нужны.
Спецификация flexbox предоставляет два метода выравнивания элементов flex вдоль главной оси:
- Свойство ключевого слова
justify-content
и -
auto
наценки
обосновывать-контент
Свойство justify-content
выравнивает элементы flex вдоль главной оси контейнера flex.
Он применяется к гибкому контейнеру, но влияет только на гибкие элементы.
Есть пять вариантов выравнивания:
-
flex-start
~ Flex элементы упакованы в начале строки.
-
flex-end
~ Flex элементы упакованы в конце строки.
-
center
~ Flex элементы упакованы по направлению к центру линии.
-
space-between
~ Flex элементы расположены равномерно, первый элемент выровнен по одному краю контейнера, а последний элемент выровнен по противоположному краю. Края, используемые первым и последним элементами, зависят от flex-direction
и режима записи (ltr
или rtl
).
-
space-around
~ То же, что и space-between
за исключением того, что на обоих концах есть пробелы половинного размера
Авто наценки
С auto
полями гибкие элементы могут быть отцентрированы, разнесены или упакованы в подгруппы.
В отличие от justify-content
, который применяется к контейнеру flex, auto
поля применяются к элементам flex.
Они работают, потребляя все свободное пространство в указанном направлении.
Выровняйте группу изгибаемых элементов справа, но первый элемент слева
Сценарий из вопроса:
-
выравнивание группы элементов Flex по правому justify-content: flex-end
(justify-content: flex-end
), но выравнивание первого элемента по левому краю (justify-self: flex-start
)
Рассмотрим заголовок раздела с группой элементов навигации и логотипом. С помощью justify-self
логотип может быть выровнен по левому краю, в то время как элементы навигации остаются далеко вправо, и все это плавно настраивается ("изгибается") на различные размеры экрана.
Другие полезные сценарии:
Поместите гибкий элемент в угол
Сценарий из вопроса:
- размещение гибкого элемента в углу
.box { align-self: flex-end; justify-self: flex-end; }
.box { align-self: flex-end; justify-self: flex-end; }
Центрируйте гибкий элемент по вертикали и горизонтали
margin: auto
является альтернативой justify-content: center
и align-items: center
.
Вместо этого кода в контейнере flex:
.container {
justify-content: center;
align-items: center;
}
Вы можете использовать это на элементе flex:
.box56 {
margin: auto;
}
Эта альтернатива полезна при центрировании гибкого элемента, который переполняет контейнер.
Отцентрируйте гибкий элемент и отцентрируйте второй гибкий элемент между первым и краем
Гибкий контейнер выравнивает гибкие элементы, распределяя свободное пространство.
Следовательно, чтобы создать равный баланс, чтобы средний элемент мог быть центрирован в контейнере с одним элементом рядом, необходимо ввести противовес.
В приведенных ниже примерах невидимые третьи гибкие элементы (вставки 61 и 68) представлены для уравновешивания "реальных" предметов (вставки 63 и 66).
Конечно, этот метод не является чем-то большим с точки зрения семантики.
В качестве альтернативы вы можете использовать псевдоэлемент вместо фактического элемента DOM. Или вы можете использовать абсолютное позиционирование. Здесь рассматриваются все три метода: гибкие элементы по центру и снизу.
ПРИМЕЧАНИЕ. Приведенные выше примеры будут работать - с точки зрения истинного центрирования - только когда самые внешние элементы будут равны высоте/ширине. Когда гибкие элементы имеют разную длину, см. Следующий пример.
Центрируйте гибкий элемент, когда соседние элементы различаются по размеру
Сценарий из вопроса:
-
в ряду из трех элементов flex прикрепите средний элемент к центру контейнера (justify-content: center
) и выровняйте соседние элементы по краям контейнера (justify-self: flex-start
и justify-self: flex-end
).
Обратите внимание, что значения space-around
и space-between
justify-content
свойстве justify-content
не будут удерживать средний элемент по центру относительно контейнера, если смежные элементы имеют разную ширину (см. Демонстрацию).
Как уже отмечалось, если все изгибаемые элементы не имеют одинаковую ширину или высоту (в зависимости от 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>
Ответ 2
Я знаю, что это не ответ, но я бы хотел внести свой вклад в этот вопрос, чтобы он того стоил. Было бы здорово, если бы они могли выпустить justify-self
для flexbox, чтобы сделать его по-настоящему гибким.
По моему убеждению, когда на оси несколько элементов, наиболее логичным способом для justify-self
для себя является выравнивание с ближайшими соседями (или ребром), как показано ниже.
Я искренне надеюсь, что W3C это заметит и, по крайней мере, рассмотрит. знак равно
Таким образом, вы можете иметь элемент, который действительно центрирован, независимо от размера левой и правой рамки. Когда один из боксов достигает точки центрального бокса, он будет просто толкать его, пока не останется больше места для распределения.
Простота создания потрясающих макетов бесконечна, взгляните на этот "сложный" пример.
Ответ 3
Это было задано в списке в стиле www, и Таб Аткинс (редактор спецификаций) дал ответ, объясняющий почему. Я подробно остановлюсь здесь.
Для начала давайте предположим, что наш flex-контейнер однострочный (flex-wrap: nowrap
). В этом случае существует четкая разница выравнивания между главной осью и поперечной осью - на главной оси есть несколько элементов, уложенных друг на друга, но только один элемент расположен на поперечной оси. Таким образом, имеет смысл иметь настраиваемое для каждого элемента "align -self" по поперечной оси (поскольку каждый элемент выравнивается отдельно, отдельно), тогда как это не имеет смысла на главной оси (так как там, пункты выровнены все вместе).
Для многострочного flexbox та же логика применяется к каждой "гибкой линии". В данной строке элементы выровнены по отдельности по перекрестной оси (поскольку в поперечной оси имеется только один элемент на линию) по сравнению с общей на главной оси.
Вот еще один способ сформулировать это: так, все свойства *-self
и *-content
касаются того, как распределить дополнительное пространство вокруг вещей. Но главное отличие заключается в том, что *-self
версия для случаев, когда существует только одна вещь в этой оси, а *-content
версии являются когда есть потенциально много вещей в этой оси. Сценарии "одно против многих" - это разные типы проблем, поэтому у них есть разные типы опций - например, значения space-around
/space-between
имеют смысл для *-content
, но не для *-self
.
SO: На главной оси flexbox есть много вещей, чтобы распределить пространство вокруг. Так что *-content
имеет смысл свойство *-content
, но не свойство *-self
.
В противоположность этому, на поперечной оси мы имеем *-self
и *-content
. Один определяет, как мы будем распределять пространство вокруг множества align-content
линий (align-content
), тогда как другой (align-self
) определяет, как распределить пространство вокруг отдельных элементов align-self
на поперечной оси в пределах данной линии изгиба.
(Я игнорирую свойства *-items
здесь, так как они просто устанавливают значения по умолчанию для *-self
.)
Ответ 4
Ответ (temporaly) добавлен здесь для Центрирование определенного элемента среди других с помощью flexbox, и это не о том, почему, но как...
justify-content или margin: auto будет устанавливать равные поля между элементами.
Вам нужно как-то добавить ширину, отсутствующую в коротком дочернем элементе.
Вы можете использовать javascript для вычисления кратчайшего и краткого добавления этого поля. CSS не будет сам. (в futur display: grid будет)
.flex-container {
display: flex;
justify-content:space-between;
align-items: center;
background:linear-gradient(to left ,transparent 50%, rgba(0,0,0,0.2) 50%),linear-gradient(to top,transparent 50%, rgba(0,0,0,0.2) 50%)
}
.flex-item:first-child {
margin-right:100px;/* + 50px equals width of the last one */
}
.flex-item {
max-width:50px;
box-shadow:0 0 0 1px;
}
div ~.flex-item {
max-width:150px;
}
div.plz-center {
max-width:25px;
background:linear-gradient(to right ,transparent 50%, rgba(200,0,0,0.2) 50%),linear-gradient(to bottom,transparent 50%, rgba(200,0,0,0.2) 50%)
}
<div class="flex-container">
<div class="flex-item"> computed width of 50px </div>
<div class="flex-item plz-center"> computed width of 25px </div>
<div class="flex-item"> computed width of 150px </div>
</div>
Ответ 5
Я знаю, что это не использует flexbox, но для простого варианта использования из трех элементов (один слева, один в центре, один справа) это можно легко сделать с помощью display: grid
на родительском элементе, grid-area: 1/1/1/1;
на детей, и justify-self
для позиционирования этих детей.
<div style="border: 1px solid red; display: grid; width: 100px; height: 25px;">
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: left;"></div>
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: center;"></div>
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: right;"></div>
</div>
Ответ 6
Существует justify-self
, но в Chrome Canary, а не в стабильной версии Chrome. Существует даже justify-items
:
Но насколько я могу сказать, эти свойства тоже не работают. Вероятно, Google заранее сохранил его для будущих выпусков CSS. Можно только надеяться, что они скоро добавят свойства.