In the example below I desire to get all items to be the width of largest content (e.g item 5).
The number of items in the list is dynamic and there could be hundred of them.
The width of each item content is also dynamic.
The number of items in each row would vary dependant on the width of the container.
DESIRED OUTPUT
Note: Media queries won't work for my scenario.
USING CSS FLEX
Flex
is considered to be one dimensional. This means it can achieve the desired result on a single axis (row) unless the content is smaller than the available space.
Non wrapping example (Single row)
.container {
display: flex;
}
.item {
background: #58c;
text-align: center;
white-space: nowrap;
margin: 0 10px 10px 0;
flex: 1;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
Flex's flex-wrap
attribute can be used to create a two dimensional layout. Again this works nice but requires a fixed width value in order to calculate each items width.
Wrapping example (Multiple rows)
.container {
display: flex;
flex-wrap:wrap;
}
.item {
background: #58c;
text-align: center;
white-space: nowrap;
margin: 0 10px 10px 0;
flex: 0 1 100px;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
USING CSS GRID
For two dimensional design, CSS Grid is recommended but the example below is using a fixed width. It seems like min-content
needs factoring in here, but how?
Failed example
grid-template-columns: repeat(auto-fit, min-content);
FIXED EXAMPLE (Multple rows)
.container {
display: grid;
grid-template-columns: repeat(auto-fit, 100px);
grid-auto-rows: 20px;
grid-gap: 5px;
}
.item {
background: #58c;
text-align: center;
white-space: nowrap;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
I do not think this is achievable with grid because of the following W3C note:
"Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes."
Fundamentally I think there is no intrinsic way to do this with css.
To get the width of each item it needs to be:
I see no way to infer an items width from another row AND column simultaneously.
You can simply use the CSS display property with the value inline-block to make a <div> not larger than its contents (i.e. only expand to as wide as its contents).
This seems like a problem that CSS Grid should be able to handle. But I haven't seen anything in the spec that provides a solution. I'm not saying it's not there, either as one simple command or a combination of rules. I just haven't found it (if it exists).
Here's the closest I've been able to get:
.container {
display: grid;
grid-auto-columns: min-content; /* max-content works, as well */
grid-gap: 10px;
}
.item {
background: #58c;
text-align: center;
white-space: nowrap;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
The code above solves the width problem — all items are the length of the longest item. But there's no wrapping. The problem is flipped in the example below.
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min-content, 1px));
grid-gap: 10px;
}
.item {
background: #58c;
text-align: center;
white-space: nowrap;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5 is longer</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
The code above gets the wrapping going, and gets around the intrinsic size limitation when using repeat()
. However, the longest-content equal length requirement fails.
Automatic repetitions (
auto-fill
orauto-fit
) cannot be combined with intrinsic or flexible sizes.
An intrinsic sizing function is
min-content
,max-content
,auto
,fit-content()
.A flexible sizing function is
<flex>
(fr
).
You can get around the auto
limitation with something like this:
repeat(auto-fill, minmax(min-content, 1px))
minmax(min,max)
Defines a size range greater than or equal to min and less than or equal to max.
If max < min, then max is ignored and
minmax(min,max)
is treated as min.As a maximum, a
<flex>
value sets the track’s flex factor; it is invalid as a minimum.
Maybe somebody else can take it from here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With