A trick you may want to know: The first step of programming is to find similarities out of differences.
Our two layouts both have two big blocks, one bar and a number of smaller blocks (12 in desktop and 10 in tablet). That makes our HTML look like this (the order mostly doesn't matter, but only mostly; we'll address that later):
<div id="layout">
<div class="square" id="square-1">Content</div>
<div class="square" id="square-2">Content</div>
<div class="bar">Content</div>
<div class="product">Product 1</div>
<div class="product">Product 2</div>
<div class="product">Product 3</div>
<div class="product">Product 4</div>
<div class="product">Product 5</div>
<div class="product">Product 6</div>
<div class="product">Product 7</div>
<div class="product">Product 8</div>
<div class="product">Product 9</div>
<div class="product">Product 10</div>
<div class="product">Product 11</div>
<div class="product">Product 12</div>
</div>
We have 2 big blocks, both span 2 rows and 2 columns. One starts at the 2nd row and span the last 2 columns, the other at the 5th row and span the first 2 columns. We translate that into CSS accordingly:
.square {
grid-row-end: span 2;
grid-column-end: span 2;
}
#square-1 {
grid-row-start: 2; /* The 2nd horizontal line */
grid-column-start: -3; /* The 3rd from last vertical line */
}
#square-2 {
grid-row-start: 5; /* The 5th horizontal line */
grid-column-start: 1; /* The first vertical line */
}
The bar starts at the 4th row and span all columns. Make sure we add that as well:
.bar {
grid-row: 4 / span 1;
grid-column: 1 / -1;
}
Our layout is a grid
which originally has 4 columns. Since we need to change this in tablet view, let's use a CSS variable. We'll also use grid-auto-rows: 1fr
as the rows need to have equal height:
#layout {
--columns: 4;
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
grid-auto-rows: 1fr;
}
On tablet, we expects 3 columns. Simply change the CSS variable we specified above to reflect that. Also, the last two products need to be hidden as they will ruin our layout; note that these two must be the last two children of #layout
for the selector to work:
@media only screen and (max-width: 1000px) {
#layout {
--columns: 3;
}
.product:nth-last-child(-n + 2) {
display: none;
}
}
Try it:
#layout {
--columns: 4;
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
grid-auto-rows: 1fr;
}
.square {
grid-row-end: span 2;
grid-column-end: span 2;
}
.bar {
grid-row: 4 / span 1;
grid-column: 1 / -1;
}
#square-1 {
grid-row-start: 2;
grid-column-start: -3;
}
#square-2 {
grid-row-start: 5;
grid-column-start: 1;
}
@media only screen and (max-width: 1000px) {
#layout {
--columns: 3;
}
.product:nth-last-child(-n + 2) {
display: none;
}
}
/* Demo only */
#layout {
gap: 5px;
}
:where(#layout) > * {
display: flex;
align-items: center;
justify-content: center;
background: #ddd;
}
.product, .square {
aspect-ratio: 1 / 1;
}
<div id="layout">
<div class="square" id="square-1">Content</div>
<div class="square" id="square-2">Content</div>
<div class="bar">Content</div>
<div class="product">Product 1</div>
<div class="product">Product 2</div>
<div class="product">Product 3</div>
<div class="product">Product 4</div>
<div class="product">Product 5</div>
<div class="product">Product 6</div>
<div class="product">Product 7</div>
<div class="product">Product 8</div>
<div class="product">Product 9</div>
<div class="product">Product 10</div>
<div class="product">Product 11</div>
<div class="product">Product 12</div>
</div>