В CSS Flexbox, почему нет свойств «justify-items» и «justify-self»?

292

Рассмотрим основную ось и поперечную ось гибкого контейнера:

Изображение 359                                                                                                                       Источник: 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>

jsFiddle версия


На момент написания этой статьи в flexbox spec не упоминается justify-self или justify-items.

Однако в модуле выравнивания CSS-боксов, который является незавершенным предложением W3C, чтобы установить общий набор свойств выравнивания для использования во всех коробчатых моделях, есть это

Изображение 360                                                                                                                         Источник: W3C

Вы заметите, что justify-self и justify-items рассматриваются... но не для flexbox.


Я закончу, повторив основной вопрос:

Почему нет свойств "justify-items" и "justify-self"?

  • 3
    Как вы ожидаете, что justify-self будет работать на гибкий элемент? Предположим, у вас есть элементы a, b, c, d с дополнительным пространством для распределения вокруг них, а во флекс-контейнере есть justify-content: space-between , поэтому они заканчиваются как | abcd |. Что бы означало добавить, например, justify-self: center или 'justify-self: flex-end` просто к элементу' b '? Где вы ожидаете, что это пойдет? (Я вижу некоторые демонстрации в одном из ответов здесь, но я не вижу четкого способа, как это будет работать в целом.)
  • 0
    (В качестве альтернативы: предположим, что у нас есть justify-content: flex-start , поэтому элементы с самого начала переполнены, как | abcd |. Что бы вы ожидали от этого, если вы положите justify-self: [anything] в элемент 'b'? там?)
Показать ещё 3 комментария
Теги:
flexbox
language-lawyer
w3c

5 ответов

553
Лучший ответ

Методы выравнивания элементов Flex вдоль основной оси

Как указано в вопросе:

Чтобы выровнять элементы flex вдоль основной оси, существует одно свойство: justify-content

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

Затем задается вопрос:

Почему нет свойств justify-items и justify-self?

Один ответ может быть: Потому что они не нужны.

flexbox спецификация предоставляет два метода выравнивания элементов flex вдоль основной оси:

  • Свойство ключевого слова justify-content и
  • auto поля

оправдает содержание

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

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

Существует пять параметров выравнивания:

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

    Изображение 4977

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

    Изображение 4978

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

    Изображение 4979

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

    Изображение 4980

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

    Изображение 4981


Автополя

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

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


Выровняйте группу элементов flex вправо, но первый элемент влево

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

  • создание группы элементов flex align-right (justify-content: flex-end) но первый элемент выравнивается влево (justify-self: flex-start)

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

Изображение 4982

Изображение 4983


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

Изображение 4984

Изображение 4985

Изображение 4986


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

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

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

Изображение 4987


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

Изображение 4988

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

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

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

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

.box56 {
    margin: auto;
}

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


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

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

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

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

Изображение 4989

Изображение 4990

Конечно, этот метод не имеет ничего общего с семантикой.

В качестве альтернативы вы можете использовать псевдоэлемент вместо фактического элемента DOM. Или вы можете использовать абсолютное позиционирование. Здесь описаны все три метода: Центры и нижние выравнивающие элементы

ПРИМЕЧАНИЕ. Приведенные выше примеры будут работать только – с точки зрения истинного центрирования – когда самые внешние предметы равны высоте/ширине. Когда элементы гибкости различной длины, см. Следующий пример.


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

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

  • в строке из трех элементов гибкости, прикрепите средний элемент к центру контейнера (justify-content: center) и выровняйте соседний элементов к краям контейнера (justify-self: flex-start и justify-self: flex-end).

    Обратите внимание, что значения space-around и space-between в свойстве 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>

Вот два метода решения этой проблемы:

Решение №1: Абсолютное позиционирование

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

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

В приведенных ниже примерах средний элемент центрируется с абсолютным позиционированием, а внешние элементы остаются в потоке. Но один и тот же макет можно выполнить обратным образом: центрировать средний элемент с помощью justify-content: center и полностью позиционировать внешние элементы.

Изображение 4991

Решение # 2: Вложенные контейнеры Flex (без абсолютного позиционирования)

.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) является контейнером flex.
  • Каждый дочерний div (.box) теперь является гибким элементом.
  • Каждому элементу .box предоставляется flex: 1, чтобы распределить контейнерное пространство одинаково.
  • Теперь элементы потребляют все пространство в строке и имеют равную ширину.
  • Сделайте каждый элемент контейнером (вложенным) и добавьте justify-content: center.
  • Теперь каждый элемент span представляет собой элемент с центром в центре.
  • Используйте поля flex 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 псевдоэлементы на контейнере flex.

Изображение 4992

(кредит: @oriol для кода и @crl для ярлыка)

ОБНОВЛЕНИЕ: Браузеры начали внедрять space-evenly, что и позволяет сделать это. Подробнее см. В этом сообщении: Равное расстояние вокруг элементов гибкости


PLAYGROUND (включает код для всех приведенных выше примеров)

  • 0
    Ответ выше охватывает основную ось , justify-content и auto поля. Для другой стороны монеты - поперечной оси , align-items , align-self и align-content - см. Этот пост: stackoverflow.com/q/42613359/3597276
  • 0
    Хорошие примеры, но центрирующий аспект все еще нетривиален. Как бы вы скорректировали Решение № 2: Вложенные Flex-контейнеры, когда среднее число элементов окружено неравномерным? Посмотрите этот пример , где контейнерный подход приводит к тому, что центральный элемент слегка смещен относительно абсолютного центра, если у нас есть два элемента справа. Как вы заметили, абсолютное позиционирование имеет тот недостаток, что оно удаляется из потока документов, что тоже не идеально.
Показать ещё 10 комментариев
62

Я не знаю ответа, но мне нравится вносить свой вклад в это дело. Было бы здорово, если бы они выпустили justify-self для flexbox, чтобы сделать его действительно гибким.

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

Я действительно надеюсь, W3C наблюдает за этим и, по крайней мере, рассмотрит его. =)

Изображение 4993

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

Изображение 4994

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

Изображение 4995

  • 7
    @ Марк, это потрясающе! Спасибо, что нашли время, чтобы составить это. Я надеюсь, что вы не возражаете, но я представил это здесь: discourse.wicg.io/t/flexbox-justify-self-property/1146
  • 0
    @Zaqx уверен, чем больше выдержка, тем лучше. Серьезно надеюсь, что они найдут способ воплотить это в реальность, очень хотелось бы запачкать мои руки на этом.
Показать ещё 3 комментария
6

Это было задано в списке www-style, а Tab Atkins (редактор спецификаций) предоставил ответ, объясняющий, почему. Я расскажу об этом немного.

Чтобы начать, сначала предположим, что наш контейнер flex является однострочным (flex-wrap: nowrap). В этом случае, очевидно, разность выравнивания между главной осью и поперечной осью - на главной оси расположено множество элементов, но только одна позиция укладывается в поперечную ось. Таким образом, имеет смысл иметь настраиваемое значение "align-self" в поперечной оси (так как каждый элемент выравнивается отдельно, сам по себе), тогда как он не имеет смысла на главной оси (поскольку там, элементы выравниваются вместе).

Для многострочного flexbox та же логика применяется к каждой "гибкой линии". В заданной строке элементы выравниваются по отдельности на поперечной оси (поскольку на главной оси имеется только один элемент), а вместе с ним и на главной оси.


Вот еще один способ его формулировки: поэтому все свойства *-self и *-content описывают, как распределять лишнее пространство вокруг вещей. Но ключевое различие заключается в том, что версии *-self предназначены для случаев, когда в этой оси есть только одна вещь, а версии *-content - для тех случаев, когда на этой оси имеется много вещей. В сценариях "одна вещь" или "много вещей" есть разные типы проблем, поэтому они имеют разные типы доступных параметров - например, значения space-around/space-between имеют смысл для *-content, но не для *-self.

SO: На главной оси flexbox существует множество возможностей для распределения пространства вокруг. Таким образом, свойство *-content имеет смысл, но не свойство *-self.

Напротив, на поперечной оси мы имеем свойство a *-self и a *-content. Один определяет, как мы будем распределять пространство вокруг многих гибких линий (align-content), и каждый определяет, как распределять пространство вокруг отдельных элементов гибкости в поперечной оси в пределах данной гибкой линии.

(Я игнорирую свойства *-items здесь, так как они просто устанавливают значения по умолчанию для *-self.)

  • 1
    Я понимаю, как justify-self может быть проблемой на оси с несколькими элементами в отличие от одного элемента. Однако я действительно надеюсь, что они рассмотрят это дальше, в ситуации с несколькими пунктами, как бы себя justify-self , потому что в некоторых ситуациях это может быть действительно полезным. Например ( stackoverflow.com/questions/32378953/… ).
  • 0
    Хорошая находка в этом списке рассылки. Попытка обернуть голову вокруг этого, поскольку я все еще вижу хорошие варианты использования для justify-self .
Показать ещё 2 комментария
1

Ответ (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>

justify-self и margin:auto могут быть эффективными.

.flex-container {
  display: flex;
  justify-content:center;
  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 {
  max-width:50px;
  box-shadow:0 0 0 1px;
  justify-self:flex-start;
  }
.plz-center ~.flex-item {
  max-width:150px;
  justify-self:flex-end;
  }
div.plz-center {
  max-width:25px;
  margin:auto;
  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>
0

Существует justify-self, но в Chrome Canary, а не в стабильной версии Chrome. Существует даже justify-items:

Изображение 4996

Но насколько я могу сказать, эти свойства тоже не работают. Вероятно, Google заранее сохранил его для будущих выпусков CSS. Можно только надеяться, что они скоро добавят свойства.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню