Reputation: 1443
Is there a way to use grid layout with grid gaps and missing grid-areas without leaving extra gaps in the layout.
.main {
display: grid;
grid-template-columns: 1fr 1fr;
width: 500px;
}
.container {
display: grid;
grid-template-columns: 1fr;
grid-template-areas: 'a' 'b' 'c' 'd';
width: 200px;
grid-gap: 10px;
}
.a, .b, .c, .d {
border: 1px solid black;
width: 200px;
}
.a {
grid-area: a;
}
.b {
grid-area: b;
}
.c {
grid-area: c;
}
.d {
grid-area: d;
}
<div class="main">
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="d">D box</div>
</div>
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="c">C box</div>
<div class="d">D box</div>
</div>
</div>
You can see that there is a gap between B and D when C is absent from the layout.
Other than changing to a flex layout (non-grid display), is there a way to avoid this?
Thanks, Srikanth
Upvotes: 2
Views: 1035
Reputation: 371113
The answer is yes. Remove grid-template-areas
and its related grid-area
rules.
.main {
display: grid;
grid-template-columns: 1fr 1fr;
width: 500px;
}
.container {
display: grid;
grid-template-columns: 1fr;
/* grid-template-areas: 'a' 'b' 'c' 'd'; */
width: 200px;
grid-gap: 10px;
}
.a, .b, .c, .d {
border: 1px solid black;
width: 200px;
}
/*
.a { grid-area: a; }
.b { grid-area: b; }
.c { grid-area: c; }
.d { grid-area: d; }
*/
<div class="main">
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="d">D box</div>
</div>
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="c">C box</div>
<div class="d">D box</div>
</div>
</div>
When you create a grid using grid-template-areas
, keep these points in mind:
grid-template-areas
creates an explicit grid."a"
, "b"
, "c"
, "d"
), that creates four explicit rows. These rows exist with or without grid items.So your best bet is to switch from explicit rows, which are defined using grid-template-areas
and/or grid-template-rows
, to implicit rows, which allow the grid algorithm to create row tracks as needed to accommodate items.
If you remove grid-template-areas
and grid-area
from your ruleset, the grid will automatically lay out the grid items in a single column (as you have defined), and it has no reason to skip rows/leave gaps. Here's the code again from above:
.main {
display: grid;
grid-template-columns: 1fr 1fr;
width: 500px;
}
.container {
display: grid;
grid-template-columns: 1fr;
/* grid-template-areas: 'a' 'b' 'c' 'd'; */
width: 200px;
grid-gap: 10px;
}
.a, .b, .c, .d {
border: 1px solid black;
width: 200px;
}
/*
.a { grid-area: a; }
.b { grid-area: b; }
.c { grid-area: c; }
.d { grid-area: d; }
*/
<div class="main">
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="d">D box</div>
</div>
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="c">C box</div>
<div class="d">D box</div>
</div>
</div>
If you don't want the grid items to consume all free space, then use align-content: start
, which overrides the default align-content: stretch
:
.main {
display: grid;
grid-template-columns: 1fr 1fr;
width: 500px;
}
.container {
display: grid;
grid-template-columns: 1fr;
/* grid-template-areas: 'a' 'b' 'c' 'd'; */
align-content: start; /* new */
width: 200px;
grid-gap: 10px;
}
.a, .b, .c, .d {
border: 1px solid black;
width: 200px;
}
/*
.a { grid-area: a; }
.b { grid-area: b; }
.c { grid-area: c; }
.d { grid-area: d; }
*/
<div class="main">
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="d">D box</div>
</div>
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="c">C box</div>
<div class="d">D box</div>
</div>
</div>
Lastly, if you want each implicit row to have a certain height, use grid-auto-rows
:
.main {
display: grid;
grid-template-columns: 1fr 1fr;
width: 500px;
}
.container {
display: grid;
grid-template-columns: 1fr;
/* grid-template-areas: 'a' 'b' 'c' 'd'; */
align-content: start; /* new */
grid-auto-rows: 40px; /* new */
width: 200px;
grid-gap: 10px;
}
.a, .b, .c, .d {
border: 1px solid black;
width: 200px;
}
/*
.a { grid-area: a; }
.b { grid-area: b; }
.c { grid-area: c; }
.d { grid-area: d; }
*/
<div class="main">
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="d">D box</div>
</div>
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="c">C box</div>
<div class="d">D box</div>
</div>
</div>
Upvotes: 2
Reputation: 114990
If you remove the grid-template-areas
this works out of the box
.container {
display: inline-grid;
grid-template-columns: 1fr;
width: 200px;
grid-gap: 10px;
margin: 1em;
}
.a,
.b,
.c,
.d {
border: 1px solid black;
width: 200px;
}
<div class="main">
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="d">D box</div>
</div>
<div class="container">
<div class="a">A box</div>
<div class="b">B box</div>
<div class="c">C box</div>
<div class="d">D box</div>
</div>
</div>
Upvotes: 0