Morgan Morgan - 1 month ago 11
CSS Question

min-width rendering differently in flex-direction: row and flex-direction: column

I have a container with

display: flex
and
flex-direction: row
.

In that container there is a sub-container also with
display: flex
but with
flex-direction: column
.

The problem is if I add an input in the sub-container, the
min-width
of that input will be ignored.

This is the code where I tried several cases of input in flexbox:



form {
margin: 100px;
}
div.flex_ctn {
display: flex;
}
input {
flex: 1;
min-width: 40px;
}
div.column {
flex-direction: column;
}
div.row {
flex-direction: row;
}
div.sub_ctn {
flex: 1;
/*min-width:40px;*/
}

<form>
<div class="flex_ctn row">
<input />
</div>
<div class="flex_ctn column">
<input />
</div>
<div class="flex_ctn row">
<div class="flex_ctn column sub_ctn">
<input />
</div>
</div>
<div class="flex_ctn column">
<div class="flex_ctn row sub_ctn">
<input />
</div>
</div>
</form>





https://fiddle.jshell.net/s3gu32ku/2/

If you reduce the screen size, the 3rd line doesn't react like the others.

In the css you will see that the last line is set as comment. When that part is enabled you just have to reload and the issue disappears. So, perfect ! I have got the solution!

But that bothers me to use something that I don't understand ^^.

This would be great if someone can explain to me why that error occurs, why that line fix it, and also if there a better way to avoid that issue.

Answer

Generally speaking, flex items, by default, cannot be smaller than the size of their content.

More specifically, these are initial settings of flex items:

  • min-width: auto (applies in flex-direction: row)
  • min-height: auto (applies in flex-direction: column)

Even more specifically, take a look at the spec language:

4.5. Implied Minimum Size of Flex Items

To provide a more reasonable default minimum size for flex items, this specification introduces a new auto value as the initial value of the min-width and min-height properties defined in CSS 2.1.

auto

On a flex item whose overflow is visible in the main axis, when specified on the flex item's main-axis min-size property, specifies an automatic minimum size. It otherwise computes to 0.

In other words, the implied minimum sizing algorithm applies only on the main axis.

Your input elements in column-direction containers don't get min-width: autobecause the main axis is vertical in those cases – so they shrink and won't overflow the container. You can see this behavior play out on your second input element. Reduce the screen size while viewing this demo.

The same thing happens with the third input, which is a child of a nested flex container with flex-direction: column... EXCEPT, this column-direction container is also a flex item of larger container with flex-direction: row.

This means the main axis of the nested container is horizontal and min-width: auto applies. As a result, this flex item will not shrink below the intrinsic width of the input. For an illustration, see the same demo from above.

Therefore, you need to override this default with min-width: 0 or overflow: hidden (demo).

And for the reasons explained above, the fourth input, contained in a nested row-direction flex-container, will also need to have min-width: auto overridden (demo).

More details here: Why doesn't flex item shrink past content size?