Почему отступ расширяет гибкий элемент?
В приведенном ниже фрагменте, первый ряд имеет два элемента div с flex-grow: 1
, Как и ожидалось, каждый div занимает 50% экрана.
При добавлении отступа к левому элементу div это уже не так. Может кто-нибудь объяснить почему?
body > div {
height: 50px;
display: flex;
}
body > div > div {
flex: 1;
box-sizing: border-box;
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#c {
padding: 10px;
background-color: blue;
}
#d {
background-color: yellow;
}
<div>
<div id="a"></div>
<div id="b"></div>
</div>
<div>
<div id="c"></div>
<div id="d"></div>
</div>
6 ответов
Расчеты определены в спецификации.
Размер гибкого элемента с подкладкой и flex-grow
определяется расчетами в спецификации flexbox.
Эти расчеты аналогичны размеру гибких элементов с отступами и flex-shrink
,
Честно говоря, математика довольно техническая и не самая легкая вещь в мире для понимания.
Но если вы хотите попасть в это, вот подробности:
Примеры
Ниже приведены примеры, которые, надеюсь, сделают поведение более понятным.
ПРИМЕЧАНИЕ: имейте в виду, что flex-grow
не является инструментом для непосредственного определения длины гибкого элемента. Это инструмент для распределения пространства в контейнере среди гибких элементов. flex-basis
Свойство устанавливает начальный основной размер гибкого элемента. Если flex-grow
используется с flex-basis
проблема в вопросе решена (см. пример № 4 ниже).
Пример № 1
В блок-контейнере, где у вас есть box-sizing: border-box
поля в вашем коде будут отображаться равномерно независимо от заполнения.
body > div {
height: 50px;
/* display: flex; */
font-size: 0; /* remove inline block whitespace */
}
body > div > div {
/* flex: 1; */
box-sizing: border-box;
height: 50px;
display: inline-block;
width: 50%;
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#c {
padding: 10px;
background-color: blue;
}
#d {
background-color: yellow;
<div>
<div id="a"></div>
<div id="b"></div>
</div>
<div>
<div id="c"></div>
<div id="d"></div>
</div>
Пример № 2
В гибком контейнере, где у вас есть box-sizing: border-box
и width
или же flex-basis
используется для расчета длины, поля будут отображаться равномерно, независимо от заполнения.
body > div {
height: 50px;
display: flex;
}
body > div > div {
flex-basis: 50%;
/* width: 50%; this works, as well */
box-sizing: border-box;
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#c {
padding: 10px;
background-color: blue;
}
#d {
background-color: yellow;
<div>
<div id="a"></div>
<div id="b"></div>
</div>
<div>
<div id="c"></div>
<div id="d"></div>
</div>
Пример № 3
В гибком контейнере, где у вас есть box-sizing: border-box
а также flex-grow
окажется, что box-sizing
не работает...
body > div {
height: 50px;
display: flex;
}
body > div > div {
flex: 1;
/* flex-basis: 50%; */
/* width: 50%; this works, as well */
box-sizing: border-box;
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#c {
padding: 10px;
background-color: blue;
}
#d {
background-color: yellow;
<div>
<div id="a"></div>
<div id="b"></div>
</div>
<div>
<div id="c"></div>
<div id="d"></div>
</div>
но это не совсем правильно...
Пример № 4
flex-grow
расширяет ширину гибкого элемента на основе доступного пространства в гибком контейнере. Другими словами, он игнорирует отступы ( и границы).
Однако, если вы просто укажите flex-grow
вместе с flex-basis
, border-box
буду работать:
flex: 1 1 50%; /* flex-grow, flex-shrink, flex-basis */
body > div {
height: 50px;
display: flex;
}
body > div > div {
flex: 1 1 50%; /* flex-grow, flex-shrink, flex-basis */
/* flex-basis: 50%; */
/* width: 50%; this works, as well */
box-sizing: border-box;
}
#a {
background-color: red;
}
#b {
background-color: green;
}
#c {
padding: 10px;
background-color: blue;
}
#d {
background-color: yellow;
<div>
<div id="a"></div>
<div id="b"></div>
</div>
<div>
<div id="c"></div>
<div id="d"></div>
</div>
Это правильное поведение, насколько я знаю.
flex:1
это, конечно, сокращение для:
flex-grow:1;
flex-shrink:1;
flex-basis:0
Это позволяет div при необходимости расти, что в данном случае и происходит. Он не будет автоматически поддерживать flex-элементы одинакового размера, если они на самом деле разные.
Tldr: Это ошибка. , Ссылка2
Альтернативное решение последнего примера Майкла Бенджамина:
Подать заявление
flex-basis: 20px /*2 X padding of sibling*/
к желтому
div#d
Как видите, оба
flex-basis: 0
а также
flex-basis: padding_left + padding_right
эквивалентны. Мало того, что любое значение <будет считаться эквивалентным
flex-basis
знак равно
padding_left + padding_right
. Что касается того, почему происходит такое поведение, я думаю, что это какая-то несогласованность / ошибка, Ссылка1предложенная здесь w3.org (снова Ссылка1) . Другими словами
box-sizing: border-box
игнорируется.
Это не ошибка, и поведение четко описано в Спецификации (ясно, но не очевидно).
Здесь речь идет о размере гибкой базы . Ты можешь читать:
Определите базовый размер гибкости и гипотетический основной размер каждого элемента:
Обратите внимание на гипотетический основной размер, который здесь является важной частью.
Каждый элемент имеет
flex:1
так
flex-basis:0
что означает размер гибкого основания, равный 0
A. Если у предмета есть определенная используемая гибкая основа, это размер гибкой основы.
Теперь продолжим до конца и прочитаем следующее:
При определении базового размера гибкого элемента минимальный и максимальный основные размеры элемента игнорируются.
До сих пор все в порядке. При нахождении базового размера гибкости мы игнорируем все.
Давай продолжим:
Гипотетическая Основной размер гибкого размера база элемента зажимается в соответствии с его использованного минимального и максимального размеров основных (и напольных покрытий размер коробки контента в нуле).
Гипотетической основной размера учитывать размер элемента , так что будет отличаться от гибкого размера базы и в нашем случае мы имеем отступы поэтому гипотетической основной размер равен
20px
Теперь, если вы проверите остальную часть алгоритма flexbox, вы заметите, что гипотетический основной размер - это тот, который используется, что дает нам логический результат увеличения элемента с заполнением.
На этом этапе размер гибкого элемента - это его внешний гипотетический основной размер.
Суммируйте внешние гипотетические основные размеры всех элементов в строке.
так далее
Тривиально, если убрать
flex-grow
Изменение свойства box-sizing на border-box в CSS включает отступы и границы в общую ширину и высоту элемента, не влияя на его размер при добавлении отступов или границ.
Обычной практикой является применение размеров коробки: border-box; глобально для всех элементов вашего CSS:
* {
box-sizing: border-box;
}
Это происходит потому, что ваш
**padding**
больше, чем
**flex-basis**
Это буквально все. Если вы просто измените это, это будет исправлено.