Flexbox
You can achieve your layout using flexbox and the order
property.
The default value of order
is 0
for all flex items. This means their order is determined by their order of appearance in the source code.
By altering the order
and flex-basis
values for items 3 and 5, they can be made to appear in the first and last rows, respectively.
.container {
display: flex;
flex-wrap: wrap;
text-align: center;
}
div {
flex: 1;
}
div:nth-child(3) {
order: -1;
flex-basis: 100%;
}
div:nth-child(5) {
order: 1;
flex-basis: 100%;
}
<section class="container">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
</section>
Alternatively, you can use invisible flex items to balance out the empty space. You would need to add 8 items with visibility: hidden
.
.container {
display: flex;
flex-wrap: wrap;
text-align: center;
}
div {
flex-basis: 20%;
}
.hidden {
visibility: hidden;
}
<section class="container">
<div class="hidden">hidden</div>
<div class="hidden">hidden</div>
<div>Item 3</div>
<div class="hidden">hidden</div>
<div class="hidden">hidden</div>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 4</div>
<div>Item 6</div>
<div>Item 7</div>
<div class="hidden">hidden</div>
<div class="hidden">hidden</div>
<div>Item 5</div>
<div class="hidden">hidden</div>
<div class="hidden">hidden</div>
</section>
Grid
This is the most flexible and robust option.
With CSS Grid, the layout is relatively simple and easy to build, and there are multiple methods one can use.
In my example below, I've used the ASCII art method of the grid-template-areas
property.
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 50px);
grid-gap: 10px;
grid-template-areas: " . . . . ."
" . . three . ."
" one two four six seven"
" . . five . ."
" . . . . ."
}
div:nth-child(1) { grid-area: one; }
div:nth-child(2) { grid-area: two; }
div:nth-child(3) { grid-area: three; }
div:nth-child(4) { grid-area: four; }
div:nth-child(5) { grid-area: five; }
div:nth-child(6) { grid-area: six; }
div:nth-child(7) { grid-area: seven; }
/* non-essential decorative styles */
.container {
width: 75%;
margin: 0 auto;
padding: 10px;
border: 1px solid black;
background-color: lightyellow;
}
div {
background-color: lightgreen;
border: 1px dashed gray;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
<section class="container">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
</section>
For a complete explanation of how these Grid properties work, and browser support data, see these posts: