Skip to content Skip to sidebar Skip to footer

Flexbox Children Shrink Up To A Certain Point (but Don't Expand If They Don't Need To)

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. What I wa

Solution 1:

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: 11 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: 11 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><divclass="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><divclass="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><divclass="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><divclass="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>

Solution 2:

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;
}
<divclass="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>

Solution 3:

Grid Solution

.container {
            width: 300px;
            border: 1px solid black;
            display: grid;
            grid-template-columns: max-content 80px80pxrepeat(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.

Post a Comment for "Flexbox Children Shrink Up To A Certain Point (but Don't Expand If They Don't Need To)"