Flexbox children shrink up to a certain point (but don't expand if they don't need to)

前端 未结 3 1921
谎友^
谎友^ 2021-01-18 05:54

I\'m a having a bit of an issue here. I have a flexbox container with children of different sizes. Based on quantity and their content children might overflow the parent.

相关标签:
3条回答
  • 2021-01-18 06:28

    Grid Solution

    .container {
                width: 300px;
                border: 1px solid black;
                display: grid;
                grid-template-columns: max-content 80px 80px repeat(2,max-content);
                padding: 5px;
            }
    

    You can use javascript to make the grid-template-column dynamic. Here is the jquery (javascript) solution using flex

    .container {
                width: max-content;
                border: 1px solid black;
                display: flex;
                padding: 5px;
            }
    
    $(".container > div").each(function(){
        ($(this).width() < 50) ?
            $(this).css('width','max-content') :
               $(this).css('flex','0 0 80px');
    })
    

    This is more dynamic than the grid solution. The only thing is that you will need to have a desired number in $(this).width() < 50 instead of fifty based on your content.

    0 讨论(0)
  • 2021-01-18 06:40

    Temani Afif's solution solves the problem of ensuring that a text element will not shrink below the specified width unless its intrinsic width is already below that width (in which case it uses its intrinsic width as the rendered width). But it does not work unless the sum of the specified widths of all the child elements exceeds the container's width.

    So I tried giving each outer elements a flex-grow parameter, so that they would grow above their specified width, if the container had room. But I also give the outer elements a maximum width set to their intrinsic maximum content width, so they would never grow beyond the actual size of the text. Thus I added the following styles to the wrapping div.

     flex: 1 1 auto;
     max-width: max-content;
    

    With that tweak I believe it solves the entire problem. The elements expand fully if there is room in the container. As we add more elements the longer elements start to shrink. But they never shrink below their specified width, so the container overflows once all inserted elements have shrunk down to that width. But elements that started with a shorter width never flex at all.

    I have added an example below.

    .container {
      width: 340px;
      border: 1px solid black;
      display: flex;
      flex-direction: row;
      padding: 5px;
    }
    
    .container>div {
      background-color: orange;
      padding: 5px;
      flex: 1 1 auto;
      width: 80px;
      max-width: max-content;
    }
    
    .container>div>div {
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      width: 100%;
    }
    
    .container>div:not(:last-child) {
      margin-right: 5px;
    }
    <h5>When the items fit they expand to their intrinsic length</h5>
    <div class="container">
      <div>
        <div>Medium length</div>
      </div>
      <div>
        <div>Tiny</div>
      </div>
      <div>
        <div>Longer text element</div>
      </div>
    </div>
    <h5>When the container limit is reached the longer elements start shrinking</h5>
    <div class="container">
      <div>
        <div>Medium length</div>
      </div>
      <div>
        <div>Tiny</div>
      </div>
      <div>
        <div>Longer text element</div>
      </div>
      <div>
        <div>Filler</div>
      </div>
    </div>
    <h5>Adding more elements...</h5>
    <div class="container">
      <div>
        <div>Medium length</div>
      </div>
      <div>
        <div>Tiny</div>
      </div>
      <div>
        <div>Longer text element</div>
      </div>
      <div>
        <div>Filler</div>
      </div>
      <div>
        <div>Filler</div>
      </div>
    </div>
    <h5>When there is no room it overflows<br> The tiny element stays at its intrinsic width, but the bigger elements stop shrinking at the specified width</h5>
    <div class="container">
      <div>
        <div>Medium length</div>
      </div>
      <div>
        <div>Tiny</div>
      </div>
      <div>
        <div>Longer text element</div>
      </div>
      <div>
        <div>Filler</div>
      </div>
      <div>
        <div>Filler</div>
      </div>
      <div>
        <div>Filler</div>
      </div>
    </div>

    0 讨论(0)
  • 2021-01-18 06:43

    With an extra wrapper you can do it:

    .container {
      width: 300px;
      border: 1px solid black;
      display: flex;
      flex-direction: row;
      padding: 5px;
    }
    
    .container > div {
      background-color: orange;
      padding: 5px;
      flex-shrink: 1;
      width: 80px;
    }
    
    .container > div > div {
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      width: 100%;
    }
    
    .container > div:not(:last-child) {
      margin-right: 5px;
    }
    <div class="container">
      <div><div>Ch 1</div></div>
      <div><div>Longer Child 2</div></div>
      <div><div>Longer Child 3</div></div>
      <div><div>Child 4</div></div>
      <div><div>Child 5</div></div>
    </div>

    0 讨论(0)
提交回复
热议问题