Рассмотрим следующий пример ...
body {
margin: 0;
}
* {
box-sizing: border-box;
}
.parent {
min-height: 100vh;
width: 50vw;
margin: 0 auto;
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.child {
border: 1px solid blue;
width: 150%;
}<div class = "parent">
<div class = "child">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet tellus cras adipiscing enim eu turpis. Neque aliquam vestibulum morbi blandit. Sem integer vitae justo eget magna.
</div>
</div>... Я ожидаю, что ребенок вырастет до width:150% и перерастет своего родителя как влево, так и вправо (поскольку он центрирован по горизонтали).
Почему этого не происходит?
Примечание: Меня интересуют ответы, взятые из официальных или надежных источников, в идеале с указанием любых ошибок или спецификаций, в которых упоминается поведение и любые возможные обходные пути.
Информация об отладке: Испытывая это в последней версии Chrome, Ubuntu 17.10. Еще не тестировал кроссбраузерность, буду обновлять, как и я.
@VXp а почему бы и нет?
Очевидно поведение по умолчанию.
Решение вашей проблемы - использовать min-width вместо width, официальная причина до сих пор не известна.
@Chiller, после того, как на него ответят и объяснят, легко понять, почему min-width "исправляет" это: браузеры не позволяют flex-basis и flex-shrink устанавливать фактическую ширину элемента ниже установленного значения min-width, если указано.
@TemaniAfif Потому что вы не ожидаете, что контейнер будет содержать что-то большее, чем он сам. Допустить, что по умолчанию - чистое безумие с точки зрения возможности понять макет; это уменьшает вашу способность предсказывать фактический размер визуализации до вашей способности знать размер каждого отдельного объекта, который визуализируется.
@TemaniAfif Другими словами, ограничение дает мне возможность полагаться на абстракции. Это позволяет мне рассматривать целую группу вещей как единое целое, что упрощает понимание происходящего и его прогнозирование.
@ jpmc26 Because you don't expect a container to contain something bigger than itself -> это поведение по умолчанию, если вы не используете технику Flexbox. Думаю, решение было принято из-за того, что по умолчанию мы можем столкнуться с нежелательным переполнением (отступы, ширина: 100% без изменения размера окна и т. д.). Поэтому они решили избежать этого переполнения и, если хотите, можете активировать его снова. Но ведь это остается спецификацией
@TemaniAfif Да, я понимаю, что исторически этого не было, и эта ситуация привела в ужас многих разработчиков. =) Вот почему я рад, что это было изменено во флексбоксе.






Нужно учитывать flex-shrink. Как вы можете прочитать здесь:
The flex-shrink CSS property specifies the flex shrink factor of a flex item. Flex items will shrink to fill the container according to the flex-shrink number, when the default size of flex items is largerthan the flex container.
body {
margin: 0;
}
* {
box-sizing: border-box;
}
.parent {
min-height: 100vh;
width: 50vw;
margin: 0 auto;
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.child {
border: 1px solid blue;
width: 150%;
flex-shrink: 0; /* added this */
}<div class = "parent">
<div class = "child">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet tellus cras adipiscing enim eu turpis. Neque aliquam vestibulum morbi blandit. Sem integer vitae justo eget magna.
</div>
</div>И как мы можем прочитать здесь также:
The flex-shrink property specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest ofthe flex items in the flex container when negative free space(1) isdistributed.
This property deals with situations where the browser calculates the flex-basis values of the flex items, and finds that they are too largeto fit into the flex container. As long as flex-shrink has a positivevalue the items will shrink in order that they do not overflow the container.
Таким образом, установив для flex-shrink значение 0, элемент никогда не сжимается, поэтому вы разрешаете переполнение (по умолчанию установлено значение 1).
(1) Negative free space: We have negative free space when the natural size of the items adds up to larger than the available space in the flex container.
Стоит отметить, что установка min-width: 150% также даст ожидаемый результат из-за другой функции flexbox, которая не позволяет гибкому элементу сжиматься за пределы своей минимальной ширины (либо явно определенной, либо внутренней).
body {
margin: 0;
}
* {
box-sizing: border-box;
}
.parent {
min-height: 100vh;
width: 50vw;
margin: 0 auto;
border: 1px solid red;
display: flex;
align-items: center;
justify-content: center;
}
.child {
border: 1px solid blue;
min-width: 150%;
}<div class = "parent">
<div class = "child">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Amet tellus cras adipiscing enim eu turpis. Neque aliquam vestibulum morbi blandit. Sem integer vitae justo eget magna.
</div>
</div>Связанный: Почему гибкие элементы не сжимаются по сравнению с размером содержимого?
больше информации о W3C здесь
@AndreiGheorghiu Я также добавил еще одну интересную ссылку, которая описывает больше этого поведения
@dippas и Afif. Несмотря на то, что теперь, когда вы указали на это, это явно "описанные в спецификациях", я все еще нахожу это довольно нелогичным: я имею в виду, зачем нужно устанавливать flex-shrink на определенное значение, когда они хотят, чтобы дочерний элемент расти превышал родительскую ширину? При обучении флексбоксу студенту нужно начинать с: «То, что вы сейчас услышите, не имеет особого смысла, но ...» Верно? Это самое последнее предложение второй цитаты, которое дает реальную причину, но будущим студентам будет сложно ее понять. Ошибка flexbox. :)
@AndreiGheorghiu Я согласен, что сначала это интуитивно понятно ... но что, если мы думаем иначе? люди всегда жалуются на переполнение из-за ширины: 100% + заполнение, когда они забывают размер блока, или некоторую границу, или поле, и т.д ... поэтому я думаю, что Flexbox поставляется с этим решением, чтобы изначально этого избежать, и по умолчанию они устанавливают flex- сжать до 1 ... тогда вы должны деактивировать его, если хотите
@AndreiGheorghiu да, верно, даже в спецификации они не указывают слово «не переполнять», они просто объясняют свойство ... так что да, это хитрая маленькая скрытая вещь, которую вам нужно поймать!
Теперь я полностью понял. Flex начинается с width, из которого он создает flex-basis. Затем он пытается уместить все гибкие дочерние элементы в гибких родительских элементах. Поскольку дочерний элемент может сжиматься, он сжимается и останется на значении width только в том случае, если его нельзя уменьшить.
@AndreiGheorghiu Я думаю, что уместно (с точки зрения интуитивного поведения), что HTML-таблицы делают то же самое: если вы устанавливаете ширину для таблицы, она действует как ограничение на размер таблицы, независимо от того, насколько широка каждая из ячеек в ней находятся. Ячейка не может выходить «за пределы» таблицы, и если она изменит размер таблицы, она больше не будет составлять 150% от новой ширины; поэтому вместо этого ячейка сжимается в зависимости от других ограничений таблицы.
Зачем ему расти дальше своего родителя?