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

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

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

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

Хотелось бы узнать, чем именно flex-base отличается от ширины на практике:

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

Изменить / уточнить: Этот вопрос был задан в другом формате в разделе Какие именно наборы свойств flex-based? но я чувствовал, что было бы неплохо более прямое сравнение или обобщение различий flex-base и width (или height).

6 ответов

Решение

Рассматривать flex-direction

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

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

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


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

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

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

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

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

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


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

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

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

7.2.3. flex-basis имущество

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

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

auto

Когда указано на гибком элементе, 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 - гибкие элементы будут выровнены по горизонтали
  • justify-content: flex-start - гибкие элементы будут складываться в начале линии на главной оси
  • align-items: stretch - гибкие элементы будут расширяться, чтобы охватить поперечный размер контейнера
  • flex-wrap: nowrap - гибкие предметы вынуждены оставаться в одной строке
  • flex-shrink: 1 - гибкий элемент может сжиматься

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

Поскольку гибкие элементы по умолчанию могут сжиматься (что предотвращает их переполнение контейнера), указанная 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 сокращение, а не его прямые свойства, так как сокращение корректно сбрасывает любые неопределенные компоненты, чтобы приспособить их к общему использованию.


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

Ошибка, затрагивающая все основные браузеры, кроме IE 11 и Edge:

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

Обнаружена проблема при определении размера элементов Flex во вложенном контейнере Flex.

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

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

Примеры:

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

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

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

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

Пример:


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

В дополнение к отличному резюме 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>

Экспериментируя с flex-grow, flex-shrink а также flex-basis (или стенография flex :fg fs fb)... может привести к некоторым интересным результатам.

Кажется, никто не упоминает, что есть одно ключевое различие между flex-basis а также width (или height, в зависимости от текущего режима записи), если мы проигнорируем аспект гибкости размера (flex-grow: 0; flex-shrink: 0;).

Это происходит из-за исключения в Flex Layout, что автоматический минимальный размер для гибких элементов по умолчанию равен min-contentвместо нуля, как обычно. Другими словами, по умолчаниюmin-width: auto вычисляет min-content вместо того 0.

В результате flex-basis (по умолчанию) ограничено ниже min-content. Если вы укажете значение меньше, чемmin-content, например flex-basis: 0, он будет вычислять min-content. По сути, это означает, что (по умолчанию) вы не можете заставить содержимое блока переполняться, поскольку блок имеет как минимум размер содержимого.

Это ключевое отличие от width, который может изменять размер окна произвольно (по умолчанию), поскольку min-width по умолчанию 0. Если значениеwidth меньше чем min-content, содержимое переполнится.

Это поведение упоминается в спецификации, но только неявно в следующем комментарии в неправильном месте в конце 7.1.1. Основные ценностиflex.

По умолчанию гибкие элементы не сжимаются ниже своего минимального размера содержимого (длины самого длинного слова или элемента фиксированного размера). Чтобы изменить это, установите свойство min-width или min-height. (См. § 4.5 Автоматический минимальный размер гибких элементов.)

Как упоминалось в комментарии, установка минимального размера снижает границу, а установка на ноль эффективно отключает ее, делая flex-basis снова веди себя как положено.

Но есть и недостатки. Во-первых, для главной оси нет свойства минимального размера. Вы должны использовать правильныйmin-width/min-height или min-block-size/min-inline-size собственность на текущий flex-direction. Если вы изменилиflex-direction, вам нужно будет снова найти правильное свойство минимального размера.

Во-вторых, flex-basisбольше не может использоваться для распределения пространства по коробкам пропорционального размера вместо простого добавления к их начальному размеру. Для получения дополнительной информации см. Рисунок 7 в спецификации.

Вот минимальный пример. Установленmin-width: 0 сделать flex-basis снова веди себя как положено.

.container {
  display: flex;
}

.container div {
  background-color: lightgrey;
  border: 1px solid black;
  margin: 0 10px;
  /* disable any flexible sizing */
  flex-grow: 0;
  flex-shrink: 0;
  /* TOGGLE ME */
  /* min-width: 0; */
}

.mincontent {
  width: min-content;
}

.smallerflexbasis {
  flex-basis: 3ex;
}

.smallerwidth {
  width: 3ex;
}
<div class="container">
  <div class="mincontent">Lorem ipsum</div>
  <div class="smallerflexbasis">Lorem ipsum</div>
  <div class="smallerwidth">Lorem ipsum</div>
</div>

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

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

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

если вы установите div min-width:600px, если размер окна меньше 600 пикселей, вы увидите горизонтальную полосу прокрутки, что не является хорошим дизайном ux.

Если вы установите его flex-basis:600px, если размер окна меньше 600 пикселей, это поле уменьшится, и вы не увидите горизонтальной полосы.

Обратите внимание, что flex-basis применяется только к гибким элементам.

Имеет значение, если вы заворачиваете.

Скажем, вы поставили ребенка на width:0и ожидайте, что это завершится, что ж, этого не произойдет. Но сflex-basis:0это завернет. (при условии, что переполнение не скрыто)

Другие вопросы по тегам