Quantcast
Channel: Active questions tagged flexbox - Stack Overflow
Viewing all articles
Browse latest Browse all 1675

Flexbox `width: max-content` and CSS specs [duplicate]

$
0
0

My question is somewhat academic because a practical solution to my problem is simple. However, I would like to understand precisely what and why happens from the CSS specification standpoint.

This question is about the same issue but it's 7 year old and it's about how, not why. I'd like to understand why this happens.

The problem

The following HTML and CSS (JSFiddle)

<div class="flex-container"><div class="flex-item">    Hello</div></div>
.flex-container {  display: flex;  width: max-content;  border: 1px solid red;}.flex-item {  flex: 0 0 200px;  border: 1px dashed blue;}

produce

  1. a flex container as wide as the text "Hello" (36px in my browser's JSFiddle) and
  2. a flex item 200px wide inside,

which leads to the child overflowing the container. The issue can be easily fixed by switching from the flex base to the good old width:

.flex-item {  flex: 0 0 auto;  width: 200px;  border: 1px dashed blue;}

But looking at the specs, I'm really confused as to why flex basis and width behave differently in this case. Moreover, it confuses my intuition which (used to tell) tells me that children of a container with width: max-content can never overflow the container because, well, we're telling the container that it can be as wide as necessary whatever the cost.

The specs

The relevant CSS specs are in CSS Flexible Box Layout Module Level 1, namely:

9.9.1. Flex Container Intrinsic Main Sizes:

The max-content main size of a flex container is the smallest size the flex container can take while maintaining the max-content contributions of its flex items, insofar as allowed by the items’ own flexibility:

For each flex item, subtract its outer flex base size from its max-content contribution size. If that result is positive, divide by its flex grow factor floored at 1; if negative, divide by its scaled flex shrink factor having floored the flex shrink factor at 1. This is the item’s max-content flex fraction.

Place all flex items into lines of infinite length.

Within each line, find the largest max-content flex fraction among all the flex items. Add each item’s flex base size to the product of its flex grow factor (or scaled flex shrink factor, if the chosen max-content flex fraction was negative) and the chosen max-content flex fraction, then clamp that result by the max main size floored by the min main size.

The flex container’s max-content size is the largest sum of the afore-calculated sizes of all items within a single line.

and 9.9.3. Flex Item Intrinsic Size Contributions:

The main-size max-content contribution of a flex item is the larger of its outer max-content size and outer preferred size (its width/height as appropriate) clamped by its flex base size as a maximum (if it is not growable) and/or as a minimum (if it is not shrinkable), and then further clamped by its min/max main size.

My reasoning is as follows.

As to 9.9.3, even though "the larger of its outer max-content size and outer preferred size (its width/height as appropriate)" is 36px because the preferred size is auto and the max content size is 36px, the clamping which occurs after that (clamped by its flex base size as a maximum (if it is not growable) and/or as a minimum (if it is not shrinkable)) should've discarded the 36px and returned the inflexible 200px.

As to 9.9.1, most of this paragraph doesn't matter because we will multiply by zero anyways in

Add each item’s flex base size to the product of its flex grow factor (or scaled flex shrink factor, if the chosen max-content flex fraction was negative) and the chosen max-content flex fraction, ...

which again gives us 200px.

The question

So, why do flex: 0 0 200px; and width: auto; return the container's max-content width as 36px, not 200px? Where is my reasoning above wrong?


Viewing all articles
Browse latest Browse all 1675

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>