I would like to lay out some elements in CSS which "flow" vertically in three or four columns, which would look like this :
The layout should put elements in the columns as evenly as possible.
A normal grid layout wouldn't work because of the vertical grid lines, and flexbox doesn't seem to offer anything with its column flow direction.
Does anyone have an idea for a good approach to laying out elements like this?
The answer depends on the sequence you want the elements to be displayed.
If you’re happy for the sequence to be column 1 top to bottom, followed by column 2 top to bottom, followed by column 3 top to bottom, then you can use CSS’s often-overlooked multi-column layout. Just style the wrapper with columns: 3
.
let s = ''
for (let i = 0; i < 20; i++) {
const hue = Math.floor(Math.random() * 256)
const height = Math.floor(Math.random() * 100) + 25
s += `<div style="border-color: hsl(${hue}, 100%, 50%); background-color: hsl(${hue}, 50%, 97%); height: ${height}px;">${i + 1}</div>`
}
document.querySelector('body').innerHTML = s
body {
margin: 1em;
columns: 3;
font-family: monospace;
font-size: 18px;
}
div {
border: 5px solid black;
margin-bottom: 1em;
break-inside: avoid;
display: flex;
justify-content: center;
align-items: center;
}
If instead you want the first three elements to be displayed at the top of columns 1, 2 and 3, and then element 4 to be displayed in whichever column is the shortest, then that’s a masonry layout. Direct support for this in CSS is being worked on, but in the meantime there are various techniques you can try.