Каковы различия между гибким основанием и шириной?

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

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

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

Я хотел бы знать, как на самом деле гибкая основа отличается от ширины:

  • Если заменить ширину на flex-basis (и наоборот), что изменится визуально?
  • Что произойдет, если я установил другое значение? Что произойдет, если они имеют одинаковое значение?
  • Существуют ли какие-то особые случаи, когда использование ширины или flex-основы будет иметь существенное значение для использования другого?
  • Как отличаются ширины и flex-основы при использовании в сочетании с другими стилями flexbox, такими как flex-wrap, flex-grow и flex-shrink?
  • Любые другие существенные различия?

Изменить/уточнить. Этот вопрос задан в другом формате в Что именно задает свойство flex-basis?, но я почувствовал более прямое сравнение или краткое изложение различий гибкости и ширины (или высоты) было бы приятным.

Ответ 1

Рассмотрим flex-direction

Первое, что приходит на ум при чтении вашего вопроса, это то, что flex-basis base не всегда применяется к width.

Когда flex-direction это row, flex-basis контролирует ширину.

Но когда flex-direction это column, flex-basis контролирует высоту.


Ключевые отличия

Вот некоторые важные различия между flex-basis и width/height:

  • flex-basis применяется только к элементам flex. Flex-контейнеры (которые также не являются flex-элементами) будут игнорировать flex-basis но могут использовать width и height.

  • flex-basis работает только на главной оси. Например, если вы находитесь в flex-direction: column, свойство width будет необходимо для определения размера элементов flex по горизонтали.

  • flex-basis не влияет на абсолютно позиционированные flex-элементы. свойства width и height будут необходимы. Абсолютно позиционированные флекс-элементы не участвуют в флекс-макете.

  • Используя свойство flex, три свойства - flex-grow, flex-shrink и flex-basis - можно аккуратно объединить в одну декларацию. Используя width, одно и то же правило потребует нескольких строк кода.


Поведение браузера

С точки зрения того, как они отображаются, не должно быть никакой разницы между flex-basis и width, если только flex-basis имеет значения auto или content.

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

7.2.3. Свойство flex-basis base

Для всех значений, кроме auto и content, flex-basis based определяется так же, как width в горизонтальных режимах записи.

Но влияние auto или content может быть минимальным или вообще ничем. Больше из спецификации:

auto

При указании в элементе flex ключевое слово auto извлекает значение свойства основного размера в качестве использованной flex-basis. Если это значение само по себе auto, тогда используемым значением является content.

content

Указывает на автоматическое изменение размера на основе содержимого элементов Flex.

Примечание. Это значение отсутствовало в первоначальном выпуске Flexible Box Layout, поэтому некоторые старые реализации его не поддерживают. Эквивалентный эффект может быть достигнут при использовании auto вместе с основным размером (width или height) auto.

Таким образом, согласно спецификации, flex-basis и width разрешаются одинаково, если только flex-basis имеет значения auto или content. В таких случаях flex-basis может использовать ширину содержимого (которую, вероятно, также будет использовать свойство width).


Коэффициент flex-shrink

Важно помнить начальные настройки гибкого контейнера. Некоторые из этих настроек включают в себя:

  • flex-direction: row - элементы Flex будут выровнены по горизонтали
  • justify-content: flex-start - элементы flex будут складываться в начале строки на главной оси
  • align-items: stretch - flex-элементы будут расширяться, чтобы охватить поперечный размер контейнера
  • flex-wrap: nowrap - Flex-элементы вынуждены оставаться в одной строке
  • flex-shrink: 1 - гибкий элемент может сжиматься

Обратите внимание на последний параметр.

Поскольку по умолчанию Flex-элементы могут сжиматься (что предотвращает их переполнение контейнера), указанная flex-basis/width/height может быть переопределена.

Например, flex-basis: 100px или width: 100px сочетании с flex-shrink: 1 не обязательно будет 100px.

Чтобы отобразить указанную ширину и сохранить ее фиксированной, вам нужно отключить сжатие:

div {
   width: 100px;
   flex-shrink: 0;
}  

ИЛИ ЖЕ

div {
  flex-basis: 100px;
  flex-shrink: 0;
}

ИЛИ, как указано в спецификации:

flex: 0 0 100px;    /* don't grow, don't shrink, stay fixed at 100px */

7.2. Компоненты гибкости

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


Ошибки браузера

В некоторых браузерах возникают проблемы с определением размера flex-элементов во вложенных flex-контейнерах.

flex-basis игнорируется во вложенном flex-контейнере. width работает.

При использовании flex-basis контейнер игнорирует размеры своих дочерних элементов, и дочерние элементы переполняют контейнер. Но со свойством width контейнер учитывает размеры своих дочерних элементов и соответственно расширяется.

Рекомендации:

Примеры:

flex-элементы с использованием flex-basis white-space: nowrap и white-space: nowrap inline-flex контейнер white-space: nowrap overflow. width работает.

Кажется, что flex-контейнер, установленный в inline-flex, не распознает flex-basis white-space: nowrap при рендеринге брата с white-space: nowrap (хотя это может быть просто элемент с неопределенной шириной). Контейнер не расширяется для размещения предметов.

Но когда свойство width используется вместо flex-basis, контейнер учитывает размеры своих дочерних элементов и соответственно расширяется. Это не проблема в IE11 и Edge.

Рекомендации:

Пример:


Ошибки, влияющие на IE 10 и 11:

Ответ 2

В дополнение к отличному резюме Michael_B стоит повторить следующее:

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

Важная часть здесь является начальной.

Само по себе это разрешает ширину/высоту до тех пор, пока не вступят в игру другие свойства роста/сжатия.

Так. ребенок с

.child {
 flex-basis:25%;
 flex-grow:1;
}

сначала он будет иметь ширину 25%, но затем сразу же увеличится настолько, насколько это возможно, пока не будут учтены другие элементы. Если их нет, он будет иметь ширину 100%/высоту.

Быстрая демонстрация:

.flex {
  width: 80%;
  margin: 1em auto;
  height: 25px;
  display: flex;
  background: rebeccapurple;
}
.child {
  flex-basis: auto;
  /* default */
  background: plum;
}
.value {
  flex-basis: 25%;
}
.grow {
  flex-grow: 1;
}
<div class="flex">
  <div class="child auto">Some Content</div>
</div>
<div class="flex">
  <div class="child value">Some Content</div>
</div>
<div class="flex">
  <div class="child grow">Some Content</div>
</div>

Ответ 3

Возможно, самый важный момент для добавления:

Что делать, если браузер не поддерживает flex? В этом случае width/height берет верх и применяются их значения.

Очень хорошая идея - почти существенная - определить width/height на элементах, даже если у вас есть совершенно другое значение для flex-basis. Не забудьте проверить, отключив display:flex и увидев, что вы получаете.