В 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 вдоль главной оси:

  1. Свойство ключевого слова justify-content и
  2. auto наценки

обосновывать-контент

Свойство justify-content выравнивает элементы flex вдоль главной оси контейнера flex.

Он применяется к гибкому контейнеру, но влияет только на гибкие элементы.

Есть пять вариантов выравнивания:

  • flex-start ~ Flex элементы упакованы в начале строки.

    enter image description here

  • flex-end ~ Flex элементы упакованы в конце строки.

    enter image description here

  • center ~ Flex элементы упакованы по направлению к центру линии.

    enter image description here

  • space-between ~ Flex элементы расположены равномерно, первый элемент выровнен по одному краю контейнера, а последний элемент выровнен по противоположному краю. Края, используемые первым и последним элементами, зависят от flex-direction и режима записи (ltr или rtl).

    enter image description here

  • space-around ~ То же, что и space-between за исключением того, что на обоих концах есть пробелы половинного размера

    enter image description here


Авто наценки

С auto полями гибкие элементы могут быть отцентрированы, разнесены или упакованы в подгруппы.

В отличие от justify-content, который применяется к контейнеру flex, auto поля применяются к элементам flex.

Они работают, потребляя все свободное пространство в указанном направлении.


Выровняйте группу изгибаемых элементов справа, но первый элемент слева

Сценарий из вопроса:

  • выравнивание группы элементов Flex по правому justify-content: flex-end (justify-content: flex-end), но выравнивание первого элемента по левому краю (justify-self: flex-start)

    Рассмотрим заголовок раздела с группой элементов навигации и логотипом. С помощью justify-self логотип может быть выровнен по левому краю, в то время как элементы навигации остаются далеко вправо, и все это плавно настраивается ("изгибается") на различные размеры экрана.

enter image description here

enter image description here


Другие полезные сценарии:

enter image description here

enter image description here

enter image description here


Поместите гибкий элемент в угол

Сценарий из вопроса:

  • размещение гибкого элемента в углу .box { align-self: flex-end; justify-self: flex-end; } .box { align-self: flex-end; justify-self: flex-end; }

enter image description here


Центрируйте гибкий элемент по вертикали и горизонтали

enter image description here

margin: auto является альтернативой justify-content: center и align-items: center.

Вместо этого кода в контейнере flex:

.container {
    justify-content: center;
    align-items: center;
}

Вы можете использовать это на элементе flex:

.box56 {
    margin: auto;
}

Эта альтернатива полезна при центрировании гибкого элемента, который переполняет контейнер.


Отцентрируйте гибкий элемент и отцентрируйте второй гибкий элемент между первым и краем

Гибкий контейнер выравнивает гибкие элементы, распределяя свободное пространство.

Следовательно, чтобы создать равный баланс, чтобы средний элемент мог быть центрирован в контейнере с одним элементом рядом, необходимо ввести противовес.

В приведенных ниже примерах невидимые третьи гибкие элементы (вставки 61 и 68) представлены для уравновешивания "реальных" предметов (вставки 63 и 66).

enter image description here

enter image description here

Конечно, этот метод не является чем-то большим с точки зрения семантики.

В качестве альтернативы вы можете использовать псевдоэлемент вместо фактического элемента 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 это заметит и, по крайней мере, рассмотрит. знак равно

enter image description here

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

enter image description here

Простота создания потрясающих макетов бесконечна, взгляните на этот "сложный" пример.

enter image description here

Ответ 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. Можно только надеяться, что они скоро добавят свойства.