I am building a Navbar for my app. I would like to have my items shrink based on their content but grow based on the average size.
All I want is:
- if there is enough space for all items to be max-content-size, I want the size to be even of all items.
- if there is enough space for all items min-content, I want the items to shrink based on their content.
- if there is not enough space for all items min-content, I want them to further shrink based on their content, so that the biggest item starts to shrink first, until it is as big as the secont biggest item, then both of them start to shrink
I could do this using grid or flex.
Unfortunately, I cannot get it the expected behavior as either they grow based on their content (and not based on the average size) or they shrink based on their average size and not based on their content. I included a snippet with two sample implementations.
body {
margin: 0;
font-family: Verdana;
}
.small {
width: 400px;
}
.medium {
width: 800px;
}
.large {
width: 1200px;
}
.container-flex {
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
border: 1px solid black;
}
.item-flex {
display: flex;
flex-direction: column;
flex-basis: auto;
flex-shrink: 1;
flex-grow: 1;
overflow: hidden;
padding: 20px;
background-color: green;
border: 1px solid red;
min-width: 0;
}
.title {
background-color: white;
flex-grow:0;
text-align: center;
vertical-align: middle;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
min-width: 0;
}
.container-grid {
display: grid;
grid-template-columns: repeat(auto-fill, 1fr);
grid-auto-columns: 1fr;
grid-auto-flow: column;
border: 1px solid black;
}
.item-grid {
display: flex;
flex-direction: column;
overflow: hidden;
padding: 20px;
background-color: green;
border: 1px solid red;
min-width: 0;
}
<div class="small">
<h2>Small</h2>
<h4>Flex</h4>
<div class="container-flex">
<div class="item-flex">
<div class="title">Title</div>
</div>
<div class="item-flex">
<div class="title">Long Title</div>
</div>
<div class="item-flex">
<div class="title">Even longer Title</div>
</div>
<div class="item-flex">
<div class="title">Title</div>
</div>
</div>
<h4>Grid</h4>
<div class="container-grid">
<div class="item-grid">
<div class="title">Title</div>
</div>
<div class="item-grid">
<div class="title">Long Title</div>
</div>
<div class="item-grid">
<div class="title">Even longer Title</div>
</div>
<div class="item-grid">
<div class="title">Title</div>
</div>
</div>
</div>
<div class="medium">
<h2>Medium</h2>
<h4>Flex</h4>
<div class="container-flex">
<div class="item-flex">
<div class="title">Title</div>
</div>
<div class="item-flex">
<div class="title">Long Title</div>
</div>
<div class="item-flex">
<div class="title">Even longer Title</div>
</div>
<div class="item-flex">
<div class="title">Title</div>
</div>
</div>
<h4>Grid</h4>
<div class="container-grid">
<div class="item-grid">
<div class="title">Title</div>
</div>
<div class="item-grid">
<div class="title">Long Title</div>
</div>
<div class="item-grid">
<div class="title">Even longer Title</div>
</div>
<div class="item-grid">
<div class="title">Title</div>
</div>
</div>
</div>
<div class="large">
<h2>Large</h2>
<h4>Flex</h4>
<div class="container-flex">
<div class="item-flex">
<div class="title">Title</div>
</div>
<div class="item-flex">
<div class="title">Long Title</div>
</div>
<div class="item-flex">
<div class="title">Even longer Title</div>
</div>
<div class="item-flex">
<div class="title">Title</div>
</div>
</div>
<h4>Grid</h4>
<div class="container-grid">
<div class="item-grid">
<div class="title">Title</div>
</div>
<div class="item-grid">
<div class="title">Long Title</div>
</div>
<div class="item-grid">
<div class="title">Even longer Title</div>
</div>
<div class="item-grid">
<div class="title">Title</div>
</div>
</div>
</div>
The different sizes are just for testing, I am asking for a responsive solution working with different contents and different number of items.
2
Answers
with 3 different container behaviors, you need to change the characteristics for the cards.
"small container cards" need a
max-width
withoverflow: hidden
andtext-overflow: ellipsis
."medium container cards" need a
min-width
and the defaultflex-shrink
disabled."large container cards" need to preset the width to have all the equal width:
The grid for larger screens does not care for the amount of child elements but will also not break by default. But without JS I don’t see a solution that could do that.
I solved it in codepen, here’s the link to the Codepen
Here is the HTML
CSS