Каковы различия между 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
,
Из спецификации:
Для всех значений, кроме
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 */
Авторам рекомендуется контролировать гибкость, используя
flex
сокращение, а не его прямые свойства, так как сокращение корректно сбрасывает любые неопределенные компоненты, чтобы приспособить их к общему использованию.
Ошибки браузера
Ошибка, затрагивающая все основные браузеры, кроме IE 11 и Edge:
flex-basis
игнорируется во вложенном гибком контейнере. width
работает.
Обнаружена проблема при определении размера элементов Flex во вложенном контейнере Flex.
Когда используешь flex-basis
, контейнер игнорирует размеры своих дочерних элементов, а дочерние объекты переполняют контейнер. Но с width
свойство, контейнер учитывает размеры своих дочерних элементов и соответственно расширяется. Это не проблема в IE11 и Edge.
Рекомендации:
- Chrome не расширяет флекс родительский по содержанию детей
- Разница между шириной и гибкой основой
- Flex-base игнорируется при определении размера вложенных flex-контейнеров.
- flex-base:100px делает что-то отличное от ширины:100px+flex-base:auto
Примеры:
- https://jsfiddle.net/t419zhra/ (источник: @Dremora)
- https://jsfiddle.net/voc9grx6/ (источник: Chromium Bugs)
- https://jsfiddle.net/qjpat9zk/ (источник: Chromium Bugs)
гибкие элементы с использованием flex-basis
а также white-space: nowrap
переполнение inline-flex
контейнер. width
работает.
Кажется, что гибкий контейнер установлен в inline-flex
не узнает flex-basis
на ребенка при рендеринге брата с white-space: nowrap
(хотя это может быть просто элемент с неопределенной шириной). Контейнер не расширяется для размещения предметов.
Но когда width
свойство используется вместо flex-basis
контейнер учитывает размер дочерних элементов и соответственно расширяется. Это не проблема в IE11 и Edge.
Рекомендации:
- ширина встроенного гибкого контейнера не увеличивается
- Встроенный гибкий контейнер (display: inline-flex) расширяет всю ширину родительского контейнера
Пример:
- https://jsfiddle.net/p18h0jxt/1/ (из первого поста выше)
Ошибки, влияющие на IE 10 и 11:
flex
стенографические объявления с единицейflex-basis
значения игнорируютсяflex-basis
не учитываетbox-sizing: border-box
flex-basis
не поддерживаетcalc()
- Важность игнорируется
flex-basis
когда используешьflex
стенография
В дополнение к отличному резюме 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
это завернет. (при условии, что переполнение не скрыто)