Reputation: 11
I'm trying to achieve a Grid-based layout where items will be laid out in a flexible grid, achieved using grid-template-columns: repeat(auto-fill, minmax(400px, 1fr))
. Items then get auto-placed into the grid, which works well.
I'd like the first item to be double-width, so it spans two columns. This is pretty easy to achieve using a rule like this:
.grid > *:first-child {
grid-column: 1/span 2;
}
However, this causes a problem once there's not enough space to fit two columns in – a second small column still appears, smaller than our minimum of 400px, and this ruins the nice regular grid on the second row onwards. My understanding is that the span 2
essentially forces the algorithm to create an extra column. Is there any option short of using JS to measure the grid container and add and remove the span 2
when there's not enough room? This grid will be used on multiple pages at different widths, so I can't just use a media query to enable/disable this behaviour.
Here's the code to reproduce the problem:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
grid-auto-columns: none;
grid-auto-rows: 300px;
}
.item {
background-color: palegreen;
border: 1px solid black;
}
.grid > *:first-child {
background-color: lightcyan;
grid-column: 1/span 2
}
<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
See this CodePen for a live example of the problem (resize the viewport to around 700px to see it).
Upvotes: 1
Views: 2334
Reputation: 31248
The simple solution would be to move the column rule into a media query. You'd need to account for the margin/padding on the document and any ancestors - on my computer, that seems to be 8px
, so a min-width: 816px
query works.
*,
::before,
::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
body {
padding: 8px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
grid-auto-rows: 50px;
}
.item {
background-color: palegreen;
border: 1px solid black;
}
.grid>*:first-child {
background-color: lightcyan;
}
@media (min-width: 816px) {
.grid>*:first-child {
grid-column: 1/span 2;
}
}
<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
Upvotes: 1