Home > database >  Flexbox: growing div with flex-basis: 0px expands too far when there's lots of content inside i
Flexbox: growing div with flex-basis: 0px expands too far when there's lots of content inside i

Time:07-18

Consider the following HTML (enter image description here

  • The enter image description here

  • CodePudding user response:

    First of all, you can remove the flex property and you will still get the same result. I am also removing the properties that won't affect the result as well:

    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan; flex-shrink: 0">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
        <p style="flex-shrink: 0">This is some text</p>
      </div>
    </div>
    
    <!-- magenta 500px indicator here added for comparison of width -->
    <div style="width: 500px; height: 5px; background-color: magenta; margin-bottom: 10px"></div>

    Now, to understand what is happening, we need to add the properties one by one.

    The initial configuration is that all the elements need to shrink so we get the following:

    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    
    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    
    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    
    <!-- magenta 500px indicator here added for comparison of width -->
    <div style="width: 500px; height: 5px; background-color: magenta; margin-bottom: 10px"></div>

    You can clearly notice that in all the 3 cases, the text will wrap in order to try to get inside the 500px. Notice the difference in the wrapping between the first and second case.

    The second case is the maximum wrapping you can have with your text since by default we cannot split words. And if you start adding more text, you will have overflow like in the 3rd case because there is no room for wrapping and for shrinking.

    Now let's introduce flex-shrink: 0 for each case

    The first one:

    .shrink p {
      flex-shrink:0;
    }
    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    <br>
    <div  style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;flex-shrink:0">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    <br>
    <div  style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    
    <!-- magenta 500px indicator here added for comparison of width -->
    <div style="width: 500px; height: 5px; background-color: magenta; margin-bottom: 10px"></div>

    By adding flex-shrink: 0 to the blue element we still have some space for the green element so it won't overflow and by adding flex-shrink: 0 to its content it will overflow but the green element won't get bigger (due to the shrink effect as well)

    Now the second case which is the case of your question:

    .shrink p {
      flex-shrink:0;
    }
    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    <br>
    
    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;flex-shrink:0;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    <br>
    
    <div  style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;flex-shrink:0;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    
    <!-- magenta 500px indicator here added for comparison of width -->
    <div style="width: 500px; height: 5px; background-color: magenta; margin-bottom: 10px"></div>

    Notice how adding flex-shrink: 0 to the blue element already create an overflow of the green one because this one cannot be smaller than its min content (when all the text is already wrapped). This is the default behavior of flex items. Adding flex-shrink:0 to its content won't change nothing because a flex item will always try to shrink but not beyond its min-width.

    That's why adding min-width:0 (or width:0) can fix this issue:

    .shrink p {
      flex-shrink:0;
    }
    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    <br>
    
    <div style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;flex-shrink:0;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    <br>
    
    <div  style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;flex-shrink:0;">
        Yo
      </p>
      <div style="display: flex; background-color: green; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    
    <br>
    
    <div  style="display: flex; background-color: blue; width: 500px;">
      <p style="width: 50px; background-color: cyan;flex-shrink:0;">
        Yo
      </p>
      <div style="display: flex; background-color: green;min-width:0; ">
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
        <p >This is some text</p>
      </div>
    </div>
    
    <!-- magenta 500px indicator here added for comparison of width -->
    <div style="width: 500px; height: 5px; background-color: magenta; margin-bottom: 10px"></div>

    Now, I let you imagine the 3rd case where we add more content. We simply increase the min-width constraint a little each time and we make the green element bigger.

    Related: Why don't flex items shrink past content size?

    • Related