I have an unknown amount of items that need to be displayed in a grid. I'd like the number of columns to auto-fill
as needed, with no limit on the number of rows. I can get this working just fine:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
list-style: none;
}
<ul class="grid">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
</ul>
However, I'd also like the items to be sorted alphabetically by column:
a d g
b e h
c f
I know I can use grid-auto-flow: column
to place each item by column instead of by row, but if I do that, I just get one long row.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-flow: column;
list-style: none;
}
<ul class="grid">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
</ul>
How can I keep the behavior of the first snippet but with sorting from top to bottom instead of from left to right?
I think the only way to do this is to consider JS and dynamically adjust the number of rows.
Here is a simplified example where you will need a more complete code if you will have gap, padding, etc
var minv = 200;
var grid = document.querySelector('.grid');
var nb = document.querySelectorAll('.grid li').length;
var nb_row = Math.ceil(nb/Math.floor(grid.offsetWidth/200));
/* grid.offsetWidth/200 = X will give the number of columns
nb/X will give the number of rows
We use floor with the first as we won't have overflow but a wrap (so 3.2 should be 3)
We use ceil with the second one as we may have the last row with fewer elements (so 3.2 should be 4)
*/
grid.style.gridTemplateRows="repeat("+nb_row+",auto)";
window.addEventListener('resize', function(event){
nb_row = Math.ceil(nb/Math.floor(grid.offsetWidth/200));
grid.style.gridTemplateRows="repeat("+nb_row+",auto)";
});
.grid {
display: grid;
grid-auto-columns: minmax(200px, 1fr);
grid-auto-flow: column;
list-style: none;
padding:0;
}
<ul class="grid">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
</ul>
You can use grid-template-rows
to limit the amount of rows, so the grid can calculate the items for each column.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-rows: repeat(3, 100px);
grid-auto-flow: column;
list-style: none;
}
<ul class="grid">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
</ul>
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