29

I have a flexbox with flex-direction: row. The child items have a min-width set. When the window is shrunk past the point where the min-width is reached, the items begin to overflow the flex container.

.parent {
  display: flex;
  flex-direction: row;
  background-color: red;
}

.child {
  min-width: 100px;
  flex-basis: 0px;
  flex-grow: 1;
  margin: 5px;
  height: 100px;
  background-color: blue;
}
<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

https://jsfiddle.net/4t8029q8/

Is there any way to force the container to stretch to contain the items without setting an explicit min-width on the parent? Doing so provides the behavior I am trying to achieve, but is too rigid to accomodate a variable number of items.

.parent {
  display: flex;
  flex-direction: row;
  background-color: red;
  min-width: 330px
}

.child {
  min-width: 100px;
  flex-basis: 0px;
  flex-grow: 1;
  margin: 5px;
  height: 100px;
  background-color: blue;
}
<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

https://jsfiddle.net/4t8029q8/1/

This is what I want, for the flex-items to never overflow the flex container even if it causes the page to need a horizontal scroll.

NOTE: I have other more complicated logic requiring flex-basis: 0px and flex-grow: 1, so those lines cannot be removed.

thedarklord47
  • 3,183
  • 3
  • 26
  • 55
  • 1
    The code snippets added by the edits don't actually show the problem due to browser width limitations on chrome. The jsfiddle link is still the best way to view the current/desired behavior. – thedarklord47 Apr 06 '22 at 20:38

4 Answers4

27

Set display: inline-flex on the .parent class to change it to an inline element. This will also force the .parent to expand to contain its children. Then by setting min-width: 100% on the .parent class, it will force it to expand to 100% of the containing element.

.parent {
  display: inline-flex;
  flex-direction: row;
  background-color: red;
  min-width: 100%;
}
.child {
  min-width: 100px;
  flex-basis: 0px;
  flex-grow: 1;

  margin: 5px;
  height: 100px;
  background-color: blue;
}
Robert O'Reilly
  • 321
  • 2
  • 2
5

You're forcing your child elements to have a specific width, much like @Michael_B mentioned, this essentially creates a static environment where they will remain the set width regardless of the parent.

Essentially at this point, since you know the min-width of your children elements, I would create a media query, at the specific width requirement, which in this case is 100px. Once your screen reaches said size, force your parent to have wrapping items by adding flex-wrap: wrap; to your parent. When you're outside the said width, be sure to set your parent's CSS back to not allow wrapping, flex-wrap: nowrap; . This will allow your child items to wrap, and your parent will create a horizontal to the page.

CaliCo
  • 388
  • 1
  • 10
1

you can use overflow-y: auto on the parent container, if scrolling doesn't matter you.

.parent {
  display: flex;
  flex-direction: row;
  overflow-y: auto;/*add this.*/
  background-color: red;
}

.child {
  min-width: 100px;
  flex-basis: 0px;
  flex-grow: 1;
  margin: 5px;
  height: 100px;
  background-color: blue;
}
<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
Sreekanth Reddy Balne
  • 3,264
  • 1
  • 18
  • 44
  • scrolling on the page is what I'm looking for, but can't have a scroll on the div itself unfortunately. – thedarklord47 Apr 27 '18 at 19:07
  • You can use `display: inline-flex` on parent container instead. But it contains the overall size of its children. The other way around is using media-queries. When the display-size reaches the desired minimum width, then change the `display: flex` to `display: inline-flex` – Sreekanth Reddy Balne Apr 27 '18 at 22:32
0

You're asking for the container to re-size fluidly in order to prevent the child elements from overflowing. This is dynamic behavior, which is the realm of JavaScript, not HTML or CSS.

Because the HTML and CSS rendering engines do not automatically re-flow the source documents when child elements overflow their container, there is no way for the container to know when the children have overflowed and, therefore, expand. You're in a static environment. The concept applies to wrapping, as well.

Here's a more detailed explanation (that covers wrapping behavior, but applies to overflow, as well):

You'll need a script or possibly media queries to make your layout work as desired.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • was going to accept, but Roberts answer actually works with no rigid widths needing to be set. care to comment on how his answer is getting around what you explained? – thedarklord47 Apr 30 '18 at 19:11
  • That answer doesn't actually answer your question: *"How to force flex parent to stretch to fit child items?"* The flex parent never expands; it remains fixed. That was the issue that I addressed, which remains valid. However, that answer does prevent the children from overflowing, which seems to be what you actually needed (so I +1). I'm glad you found a solution. – Michael Benjamin Apr 30 '18 at 19:21
  • it does expand though? I can shrink the window all the way down to where the min-width is enforced (and the items do not overflow) or grow the window as large as I want and the flex-items / parent grow unhindered. EDIT: not arguing by the way I just want to understand. – thedarklord47 Apr 30 '18 at 19:27
  • Okay, I see what you're saying. But still, there's no expansion. In your code, the container shrinks below the size of the content (never expands). In the accepted answer, it stops shrinking at the content `min-width` (but again, never expands). – Michael Benjamin Apr 30 '18 at 19:32
  • Just to be clear, since the container covers, in all cases, 100% width of the viewport, I'm not talking about screen re-sizing (where there is obvious container expansion). I'm talking about the container expanding to accommodate child elements. – Michael Benjamin Apr 30 '18 at 19:37
  • Ah I see what you mean. "Expand" is the wrong term since 100% width will "expand" with the window, but is actually a static width. Rather, it has an implicit `min-width` equal to its contents due to the `inline-flex`. As you said, preventing the overflow is really what I was after and `inline-flex` is an elegant way to do that. Am I understanding correctly? – thedarklord47 Apr 30 '18 at 19:41
  • 1
    Yes. We're on the same page now :-) – Michael Benjamin Apr 30 '18 at 19:43