Is there an analog to flex-grow
for the grid property ?
I'd like my grid areas to accomodate the content they receive but have some areas take more place than others like flex-grow
for flex
.
Practically, in the example below I'd like
turquoise
to be invisible because it accomodates its content. footer
to be invisible as well because it has no content. flex-grow
.More practically, I'd like this code:
To act like this code:
.ctnr {
display: flex;
flex-direction: column;
height: 100vh;
}
.panel {
flex-grow: 1;
display: flex;
}
header {
flex-grow: 0;
background: turquoise;
}
nav {
min-width: 10rem;
background: grey
}
footer {
background: yellow
}
<div class="ctnr">
<header>hey</header>
<div class="panel">
<nav></nav>
<main></main>
</div>
<footer></footer>
</div>
Without the div.panel
and without adding any additional tag.
The reason I would like to do this, is a legitimate one, that extra div
element is annoying me.
CSS Grid offers the fr
unit, which functions similarly to flex-grow
.
While flex-grow
distributes free space in the container among flex items, the fr
unit distributes free space in the container among rows / columns.
From the spec:
7.2.3. Flexible Lengths: the
fr
unitA flexible length or
<flex>
is a dimension with thefr
unit, which represents a fraction of the free space in the grid container.
(Note that flex-grow
is applied to flex items, while fr
lengths are applied to grid containers.)
So in your grid, you have three rows:
The first row is the header. You want the content to set its height. So its height is set to auto
.
The last row is the footer. You want the content to set its height. So its height is set to auto
.
The middle row contains the nav
and main
elements. You want this row to occupy all remaining vertical space. So its height is set to 1fr
.
.ctnr {
display: grid;
grid-template-rows: auto 1fr auto; /* key rule */
grid-template-columns: 1fr 1fr;
height: 100vh;
grid-template-areas: "header header"
"nav main"
"footer footer";
}
header {
grid-area: header;
background: turquoise;
}
nav {
grid-area: nav;
background: grey;
}
main {
grid-area: main;
background: orange;
}
footer {
grid-area: footer;
background: yellow;
}
body {
margin: 0;
}
<div class="ctnr">
<header>header</header>
<nav>nav</nav>
<main>main</main>
<footer>footer</footer>
</div>