CSS Flex positioning gotchas: child expands to more than the width allowed by the parent

Gaurav Gupta
4 min readNov 23, 2019

--

Please note that for the sake of simplicity, all of the following discussion is based on flex-direction: row

Problem Description

You have a flex container which has 4 children and it displays them in a row.

child1 has width: 48px width,
child3 has width: 48px width,
child4 has width: 150px width,
(we can also use flex-basis instead of width)
you want child2 to occupy the rest of the space, so what do you do?
set flex-grow: 1 on child2.

This works fine if the content of child2 is less than the available width, and even if the content of child2 grows, it automatically wraps to next line.

Gotcha1:
Let’s add white-space: nowrap into the mix, now something interesting happens, child2 grows as much as it wants to without being restricted, shrinks the other flex children (if they are allowed to) and extends outside the width of the parent. It seems like the parent does not control the width anymore.

Why? Would you expect it to behave this way? I certainly didn’t. I expected its width to be constrained as flex-grow: 1 should only allow it to take up the available space and not expand beyond that, and possibly show an overflow in case the text is not allowed to be wrapped.

( try setting an explicit overflow. Setting overflow: auto works, overflow: hidden works as well, and both work the same )

Explanation:

By default the min-width of a flex child is set to auto, so when the content grows beyond the available width and it can’t wrap, it is still not constrained until you set an explicit min-width (or an explicit width) on the flex child.

Gotcha 2:
Interestingly, this also works with explicitly setting the overflow property on the child in question.

But when would you like this to happen? Wouldn’t you rather wrap your content for child2 to multiple lines? Why set white-space: nowrap ?

Let’s see a use case:

You would like to fix the width for child 1, 3 and 4 and constraint child2 so that it shows ellipsis if the content of child2 is too long.

Gotcha 3:
Do remember that you always have to explicitly constraint the immediate flex child, which means if you have a child of child2 and you are trying to show ellipsis on text-overflow, you would still have to set overflow or min-width on child2

Gotcha 4:
Also, text-overflow does not work on display: flex elements, so if you want child2 content to be shown as ellipsis on overflow, you can’t set text-overflow: ellipsis on child2, instead you should just wrap the text in a container inside child2 and set the text-overflow, whitespace and overflow properties on this container, and constrain child2 using min-width/overflow/width

Gotcha 5:
you would think that width and flex-basis would work the same and constrain the flex child, seems like that isn’t the case.

Gotcha 6:
setting width: 0 and min-width: 0 has different effects,
also, both of them handle the layout fine, but the text is still overflown outside the flex parent. The behaviour seems to differ in how much overflown text is shown. min-width: 0 shrinks the other children and width: 0 does not, both of them do not let the element expand beyond the parent.
This is most likely based on the initial value considered for the calculation of flex-grow child and other children. width: 0 would start initial layout calculations from 0 and then finding out that there is empty space so growing the element, while min-width: 0 would probably start the calculation from the available space and based on that distribute the space. (I haven’t explored this yet)

Gotcha 7:
setting width: 0 or flex-basis: 0 does not actually mean the flex element would have 0 width. It is just used as an initial indication of the size and the actual size is decided based on values of other properties (for eg, the flex-grow and flex-shrink properties)

There are other combinations which can be explored, for example min-width: 0 does not seem to work with setting flex-shrink: 0 , but setting width: 0 works.

References:

  1. https://drafts.csswg.org/css-flexbox/#min-size-auto
  2. https://stackoverflow.com/questions/39884226/why-does-an-element-with-flex-1-width-0-still-have-width
  3. https://stackoverflow.com/questions/34352140/what-are-the-differences-between-flex-basis-and-width
  4. https://stackoverflow.com/questions/36968138/nested-flex-elements-dont-make-parent-grow
  5. https://stackoverflow.com/questions/7985021/css-flexbox-issue-why-is-the-width-of-my-flexchildren-affected-by-their-content/7985973#7985973
  6. https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
  7. https://westerndevs.com/css/Using-Overflow-Ellipsis-in-Inline-Flex/

--

--