Как flexbox вычисляет ширину flex-элемента, если не заданы flex-based или width? - PullRequest
1 голос
/ 13 июня 2019

Я хочу понять, как flexbox вычисляет окончательную ширину flex-элемента, когда не задано явное значение для свойств flex-basis, width, min-width или max-width.Другими словами, как flexbox вычисляет ширину flex-элемента исключительно на основе содержимого?

Вот пример кода (доступен для codepen ):

.container {
  display: flex;
  width: 600px;
}

.container div {
  outline: 1px dotted black;
}
<div class="container">
  <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
  <div>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Error ad natus dolores harum, ex fuga voluptates dignissimos possimus saepe officia.</div>
</div>

В этом примере вычисленная ширина обоих div s (flex-items) одинакова: 300px (что я вижу с помощью «inspect element»)инструменты отладки).

Теперь, если я добавлю еще 10 символов к тексту в первом элементе div ( раздвоенный код, доступный здесь ), я вижу, что первый элемент div имеет ширину 311.719px, тогда какширина второго div равна 288.281px.

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

Кроме того, должен ли я обычно практиковать явную установку свойств flex-basis или width, чтобы избежать неопределенности размера элемента, основанного насодержание?Другими словами, каковы варианты использования, чтобы не устанавливать явно ширину flex-элемента и оставить его для flexbox, чтобы определить его на основе его содержимого?

1 Ответ

4 голосов
/ 13 июня 2019

В этом конкретном случае вам необходимо учитывать эффект сжатия по умолчанию, установленный flex-shrink, который имеет значение по умолчанию 1. Первоначально ваш элемент будет переполнен, как показано ниже:

$('div').each(function() {
 console.log($(this).width());
})
.container {
  display: flex;
  width: 600px;
}

.container div {
  outline: 1px dotted black;
  flex-shrink:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
  <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>

Если вы осмотрите элементы, у вас будет 1011.3px для первого элемента и 935.3px для второго, поэтому общее переполнение будет 1011.3px + 935.3px - 600px = 1346.6px. Это переполнение будет уменьшено от обоих элементов, чтобы они могли поместиться внутри гибкого контейнера. Также следует учитывать, что элементы не будут сжиматься одинаково, поскольку они не имеют одинаковую начальную ширину. Самый большой сократится больше. Тогда у нас будет коэффициент 1011.3/935.3 = 1.08, а формула будет:

x + y = 1346.6 where y = 1.08*x

То есть x = 647px и y = 699.6px

Мы закончим с 1011.3px - 699.6px = 311.7px и 935.3px - 673.3px = 288.3px:

$('div').each(function() {
 console.log($(this).width());
})
.container {
  display: flex;
  width: 600px;
}

.container div {
  outline: 1px dotted black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
  <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>

Свойство flex-shrink указывает коэффициент сжатия Flex, который определяет степень сжатия элемента Flex относительно остальных элементов Flex в контейнере Flex при распределении отрицательного свободного пространства. исх

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

Официальная спецификация для полного алгоритма:

https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths


Имейте в виду, что существует ограничение min-width, которое может повлиять на окончательный расчет, поскольку по умолчанию элемент не может сжаться до размера его содержимого .

Здесь тот же код, что и выше, с некоторыми &nbsp;, и вы заметите, что вычисление отличается, потому что первый элемент имеет min-width ограничение, равное длине первого предложения, где у нас есть &nbsp;

$('div').each(function() {
 console.log($(this).width());
})
.container {
  display: flex;
  width: 600px;
}

.container div {
  outline: 1px dotted black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div>Lorem&nbsp;ipsum&nbsp;dolor&nbsp;sit&nbsp;amet&nbsp;consectetur&nbsp;adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
  <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>

Если вы удалите это ограничение, добавив min-width:0, вы получите предыдущие значения и некоторое переполнение:

$('div').each(function() {
 console.log($(this).width());
})
.container {
  display: flex;
  width: 600px;
}

.container div {
  outline: 1px dotted black;
  min-width:0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div>Lorem&nbsp;ipsum&nbsp;dolor&nbsp;sit&nbsp;amet&nbsp;consectetur&nbsp;adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit! 123456789</div>
  <div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga aspernatur suscipit aliquam beatae vitae harum, eius expedita quidem incidunt velit!</div>
</div>

А как насчет того, когда контент представляет собой не только текст, но и замененный контент, такой как изображения?

Применяется та же логика, на самом деле не имеет значения тип контента, все, что имеет значение, это размер элемента и min-width ограничения, которые зависят от контента.

Кроме того, должен ли я обычно практиковать явное задание свойств flex-based или width, чтобы избежать неопределенности размера элемента, основанного на содержимом?

Я бы сказал, да. У вас должен быть полный контроль над макетом, и вы не должны позволять контенту принимать решение за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...