Other posts have mentioned flexbox, but if more than one row of items is necessary, flexbox's space-between
property fails (see the end of the post)
To date, the only clean solution for this is with the
Basically the relevant code necessary boils down to this:
ul {
display: grid; /* (1) */
grid-template-columns: repeat(auto-fit, 120px); /* (2) */
grid-gap: 1rem; /* (3) */
justify-content: space-between; /* (4) */
align-content: flex-start; /* (5) */
}
1) Make the container element a grid container
2) Set the grid with an 'auto' amount of columns - as necessary. This is done for responsive layouts. The width of each column will be 120px. (Note the use of auto-fit
(as apposed to auto-fill
) which (for a 1-row layout) collapses empty tracks to 0 - allowing the items to expand to take up the remaining space. (check out this demo to see what I'm talking about) ).
3) Set gaps/gutters for the grid rows and columns - here, since want a 'space-between' layout - the gap will actually be a minimum gap because it will grow as necessary.
4) and 5) - Similar to flexbox.
body {_x000D_
margin: 0;_x000D_
}_x000D_
ul {_x000D_
display: grid;_x000D_
grid-template-columns: repeat(auto-fit, 120px);_x000D_
grid-gap: 1rem;_x000D_
justify-content: space-between;_x000D_
align-content: flex-start;_x000D_
_x000D_
/* boring properties: */_x000D_
list-style: none;_x000D_
width: 90vw;_x000D_
height: 90vh;_x000D_
margin: 2vh auto;_x000D_
border: 5px solid green;_x000D_
padding: 0;_x000D_
overflow: auto;_x000D_
}_x000D_
li {_x000D_
background: tomato;_x000D_
height: 120px;_x000D_
}
_x000D_
<ul>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
</ul>
_x000D_
Currently supported by Chrome (Blink), Firefox, Safari and Edge! ... with partial support from IE (See this post by Rachel Andrew)
Flexbox's space-between
property works great for one row of items, but when applied to a flex container which wraps it's items - (with flex-wrap: wrap
) - fails, because you have no control over the alignment of the last row of items;
the last row will always be justified (usually not what you want)
To demonstrate:
body {_x000D_
margin: 0;_x000D_
}_x000D_
ul {_x000D_
_x000D_
display: flex;_x000D_
justify-content: space-between;_x000D_
flex-wrap: wrap;_x000D_
align-content: flex-start;_x000D_
_x000D_
list-style: none;_x000D_
width: 90vw;_x000D_
height: 90vh;_x000D_
margin: 2vh auto;_x000D_
border: 5px solid green;_x000D_
padding: 0;_x000D_
overflow: auto;_x000D_
_x000D_
}_x000D_
li {_x000D_
background: tomato;_x000D_
width: 110px;_x000D_
height: 80px;_x000D_
margin-bottom: 1rem;_x000D_
}
_x000D_
<ul>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
<li></li>_x000D_
</ul>
_x000D_
Codepen (Resize to see what i'm talking about)
Further reading on CSS grids: