Ok, here\'s the situation, let\'s say I have a list with unknown number of items, it could be 10 or a 100, and I want to lay them out in 3 columns going top to bottom not le
I have a list with unknown number of items, it could be 10 or a 100
As you already observed, CSS Multi-Column Layout produces the desired layout with pure CSS - without having to know in advance the number of items in the container.
This is not the case with CSS grids - you would have to know in advance the number of items in the grid in order to calculate the necessary number of rows - which is quite a limitation.
So I would suggest you stick with Multi-Column Layout for your layout.
Assuming the above limitation is ok - then you can create the layout with css as follows:
(Note: @Ander already answered this but for what it's worth here's a small explanation)
1) On the grid container change the grid-auto-flow property to column - This lays out the grid items vertically instead of horizontally (the default).
2) Once you know the number of items, you can calculate the number of rows necessary to create a balanced grid as follows:
#rows = ceil( #items / #columns )
So for 22 items - the # rows = ceil(22/3) = 8
ul {
display: grid;
grid-auto-flow: column; /* 1 */
grid-template-rows: repeat(8, 1fr); /* 2 */
}
We can slightly improve this solution with SASS - to produce a more generic solution which calculates the number of rows. (SASS has a ceil function)
ul {
list-style: none;
padding: 0;
display:grid;
$num-items: 22;
$num-cols: 3;
$num-rows: ceil($num-items / $num-cols);
grid-template-columns: repeat($num-cols, 1fr);
grid-template-rows: repeat($num-rows, 1fr);
grid-auto-flow: column;
border: 5px solid gold;
}
FWIW: Here's an alternative solution which uses nth-child selectors without needing to change the grid-auto-flow property. Unfortunately it has the same limitation that the #items must be known in advance.
li:nth-child(-n + 24) {
grid-column: 3;
}
li:nth-child(-n + 16) {
grid-column: 2;
}
li:nth-child(-n + 8) {
grid-column: 1;
}