276

How do I make my flex item (article in this example), which has flex-grow: 1; not to overflow its flex parent/container (main)?

In this example article is just text, though it might contains other elements (tables, etc).

main, aside, article {
  margin: 10px;
  border: solid 1px #000;
  border-bottom: 0;
  height: 50px;
}
main {
  display: flex;
}
aside {
  flex: 0 0 200px;
}
article {
  flex: 1 0 auto;
}
<main>
  <aside>x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x </aside>
  <article>don't let flex item overflow container.... y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y </article>
</main>
danronmoon
  • 3,814
  • 5
  • 34
  • 56
philfreo
  • 41,941
  • 26
  • 128
  • 141
  • 101
    I had a pretty similar problem with a child table-responsive overflowing the flex item, the solution was to add `min-width: 0;` to the flex item. – Washington Guedes Aug 07 '19 at 17:41
  • 32
    I could kiss you @WashingtonGuedes your mention of min-width led me to this CSS Tricks article which describes how/why min-width solves the issue https://css-tricks.com/flexbox-truncated-text/ – Josh Dean Aug 22 '19 at 16:22
  • @WashingtonGuedes which item do u add this to i can not seem to get this right – Seabizkit Jul 07 '21 at 19:16
  • As a general answer to this question: Consider if using `display: grid` is viable alternative. It just seems to work out better for certain types of problem like this. Of course it wasn't viable when the question was asked but don't forget to consider it. – Simon_Weaver Nov 10 '22 at 06:10

11 Answers11

480

For me simply adding min-width: 0; to the overflowing div prevented the overflow:

article {
  min-width: 0;
}

Explanation:

min-width in a flex context: While the default min-width value is 0 (zero), for flex items it is auto. This can make block elements take up much more space than desired, resulting in overflow.

min-width is defined to win against competing width and max-width, meaning as soon as the element's width would shrink below its implicit auto width, min-width:auto will kick in and keep the element from shrinking.

The fix is obvious now: min-width: 0

It tells the browser that this element has no right to take up any minimum width, and now it will be rendered properly, taking up only as much width as is available.

A note about flex-shrink: While flex-shrink sounds like it could help here, it does not. The described issue is about element-sizing based on the element's content, while flex-shrink defines shrinkage relative to other flex elements in the same context. Source

orszaczky
  • 13,301
  • 8
  • 47
  • 54
123

Your flex items have

flex: 0 0 200px; /* <aside> */
flex: 1 0 auto;  /* <article> */ 

That means:

  • The <aside> will start at 200px wide.

    Then it won't grow nor shrink.

  • The <article> will start at the width given by the content.

    Then, if there is available space, it will grow to cover it.

    Otherwise it won't shrink.

To prevent horizontal overflow, you can:

  • Use flex-basis: 0 and then let them grow with a positive flex-grow.
  • Use a positive flex-shrink to let them shrink if there isn't enough space.

To prevent vertical overflow, you can

  • Use min-height instead of height to allow the flex items grow more if necessary
  • Use overflow different than visible on the flex items
  • Use overflow different than visible on the flex container

For example,

main, aside, article {
  margin: 10px;
  border: solid 1px #000;
  border-bottom: 0;
  min-height: 50px; /* min-height instead of height */
}
main {
  display: flex;
}
aside {
  flex: 0 1 200px; /* Positive flex-shrink */
}
article {
  flex: 1 1 auto; /* Positive flex-shrink */
}
<main>
  <aside>x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x </aside>
  <article>don't let flex item overflow container.... y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y </article>
</main>
Matt
  • 23,363
  • 39
  • 111
  • 152
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 5
    it seems not gonna work if I have `` inside the `
    ` even wrap the table with `div` and `overflow: auto;`
    – vee Jul 05 '17 at 10:04
  • 1
    If you are dealing with many flex items overflowing container (instead of text), you should use [flex-wrap](https://developer.mozilla.org/en/docs/Web/CSS/flex-wrap) – Jorjon Jul 07 '17 at 03:19
  • 3
    @vee when you have a to deal with the solution is to add min-width: 0 to the flex child containing the table, as explained above by Washington Guedes.
    – Istopopoki Feb 12 '20 at 15:47
  • 2
    It does not work, it never works, tested on multiple websites. Your solution is fully wrong and should be removed. – Federico Schiocchet Jun 05 '20 at 19:26
  • 6
    @vee try setting `flex: 1 1 0; min-width: 0;` on `
    ` – had the same problem with `` and it helped; see https://dev.to/martyhimmel/quick-tip-to-stop-flexbox-from-overflowing-peb
    – Matt Sep 05 '20 at 18:36
  • 1
    I've been using flexbox for years and still find all this incredibly confusing. – Matt Dec 15 '20 at 16:57
  • In Chrome, it seems this doesn't work. Horizontal scrollbars appear when you shrink the flexbox horizontally, after you pass the "preferred width" of the box, but before flex decides to wrap and put the entire box on another row. This is annoying me radically. I would simply expect flex to rather wrap the box than start putting scrollbars on it, it just feels buggy :) – BjornW Jun 15 '21 at 07:44
  • Update to my comment above: also same in Safari. I think there is some magic decision that Flexbox uses when deciding to wrap a flex child to the next row or not, that I don't understand. I guess the situation is not exactly the same as in this question about shrinking elements but related. – BjornW Jun 15 '21 at 07:52
  • Update again... I had misunderstood what flex-basis does I think. I specified it in pixels, as a hint, but it seems FlexBox takes it more seriously and relies more on that than the actual child content width in that case. Reverting it to "auto" allowed the child to avoid overflowing. Was not obvious (to me at least). Leaving my confused comments here if anyone else stumbles on it :) – BjornW Jun 15 '21 at 08:53
14

One easy solution is to use overflow values other than visible to make the text flex basis width reset as expected.

  1. Here with value auto the text wraps as expected and the article content does not overflow main container.

  2. Also, the article flex value must either have a auto basis AND be able to shrink, OR, only grow AND explicit 0 basis

main, aside, article {
  margin: 10px;
  border: solid 1px #000;
  border-bottom: 0;
  height: 50px;
  overflow: auto; /* 1. overflow not `visible` */
}
main {
  display: flex;
}
aside {
  flex: 0 0 200px;
}
article {
  flex: 1 1 auto; /* 2. Allow auto width content to shrink */
  /* flex: 1 0 0; /* Or, explicit 0 width basis that grows */
}
<main>
  <aside>x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x </aside>
  <article>don't let flex item overflow container.... y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y </article>
</main>
Pandaiolo
  • 11,165
  • 5
  • 38
  • 70
10

I know this is really late, but for me, I found that applying flex-basis: 0; to the element prevented it from overflowing.

faroukcharkas
  • 223
  • 3
  • 5
10

If you want the overflow to wrap: flex-flow: row wrap

JeanAlesi
  • 478
  • 3
  • 17
9

Instead of flex: 1 0 auto just use flex: 1

main, aside, article {
  margin: 10px;
  border: solid 1px #000;
  border-bottom: 0;
  height: 50px;
}
main {
  display: flex;
}
aside {
  flex: 0 0 200px;
}
article {
  flex: 1;
}
<main>
  <aside>x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x </aside>
  <article>don't let flex item overflow container.... y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y </article>
</main>
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
  • 11
    To clarify, `flex: 1` is like `flex: 1 1 0`. – Oriol Mar 26 '16 at 02:56
  • Awesome, thanks! I think I had the wrong mental modal for what `flex-shrink` is then since I suppose I *do* want it to shrink. Also @Oriol I think `flex: 1` is `flex: 1 1 auto`. – philfreo Mar 26 '16 at 03:25
  • 1
    @philfreo No, it is `flex: 1 1 0`. Src: https://www.w3.org/TR/css-flexbox-1/#flex-property – Asons Mar 26 '16 at 08:27
  • 1
    Hmm, why does https://developer.mozilla.org/en-US/docs/Web/CSS/flex show `auto` as the initial value for the 3rd param? – philfreo Mar 27 '16 at 17:31
  • 1
    Chrome 68 shows 0% as default flex-basis value when using `flex: 1` – Apolo Aug 24 '18 at 09:20
  • 1
    @philfreo `auto` is the initial value for `flex-basis`. If you say `flex: 1` you are in fact overriding that initial value to `0`, even though the `0` is implicit. – jbg Nov 26 '19 at 18:53
1

It's not suitable for every situation, because not all items can have a non-proportional maximum, but slapping a good ol' max-width on the offending element/container can put it back in line.

Walf
  • 8,535
  • 2
  • 44
  • 59
1

max-width works for me.

aside {
  flex: 0 1 200px;
  max-width: 200px;
}

Variables of CSS pre-processors allows to avoid hard-coding.

aside {
  $WIDTH: 200px;
  flex: 0 1 $WIDTH;
  max-width: $WIDTH;
}

overflow: hidden also works, but I lately I try do not use it because it hides the elements as popups and dropdowns.

Takeshi Tokugawa YD
  • 670
  • 5
  • 40
  • 124
1
article { width: 0; }

it also works

wangpf
  • 11
  • 3
0

I am late to the party here but here it how it works. the "parent" which has flex property decides how content will flow by default its sub divs will flow horizontally. you have to specify to flow vertically and then go from there. hope it helps.

main, aside, article {
  margin: 10px;
  border: solid 1px #000;
  border-bottom: 0;
  height: 50px;
}
main {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
     flex-direction: column;
}
aside {
  flex: 0 0 200px;
}
article {
  flex: 1 0 auto;
}
<main>
  <aside>x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x </aside>
  <article>don't let flex item overflow container.... y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y </article>
</main>
shak
  • 1
  • 1
0

For me the solution was to use max-width: 0rem; or in tailwindCSS max-w-0, the opposite of what the top-voted answer suggests.

<wrapper that is flex>
  <div className="flex max-w-0">
    overflowing content here
  </div>
</wrapper>
Michael Brenndoerfer
  • 3,483
  • 2
  • 39
  • 50