You have a few mistakes about sizing.
for a full page, and padding on body, you cannot use here min-height:100vh because it will be the viewport height being offset of 20px from the padding of body and eventually the horizontal scrollbar. Use min-height:100% instead and set body to 100vh of height. (box-sizing needs also to be reset).
width : 100% is not necessary for block element (unless you have a specific reason)
examples.
- fixing the sizing and setting footer at bottom (sticky optionnal)
body {
padding: 20px;
font-family: Helvetica;
margin: 0;
height: 100vh;/* reference for the direct child */
box-sizing: border-box;/* include padding and border into size calculation */
}
.wrapper {
display: grid;
grid-template-columns: auto;
min-height: 100%;/*of avalaible space of sized(height:xx) parent */
}
.box {
background-color: #20262e;
color: #fff;
border-radius: 3px;
padding: 20px;
font-size: 14px;
}
.a {
grid-area: 1/1/2/2;
}
.b {
grid-area: 2/1/3/2;
}
.footer {
grid-area: 4/1/5/2;
/* ?? should I stick at the bottom of the viewport ?? */
position:sticky;
bottom:0;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box footer">Footer</div>
</div>
if the footer do not need to be seen anytime, remove position:sticky and bottom:0.
- trick to follow your
grid-area settings idea (without row template) to shrink the first rows, insert an exta virtual container that will use so many rows .(not elegant and average, breaks if vertical gaps are set.)
body {
padding: 20px;
font-family: Helvetica;
margin: 0;
height: 100vh;/* reference for the direct child */
box-sizing: border-box;/* include padding and border into size calculation */
}
.wrapper {
display:grid;
min-height: 100%;/*of avalaible space of sized(height:xx) parent */
}
.box {
background-color: #20262e;
color: #fff;
border-radius: 3px;
padding: 20px;
font-size: 14px;
}
.a {
grid-area: 1/1/2/2;
}
.b {
grid-area: 2/1/3/2;
}
.footer {
grid-area: 0/1/21/2;
}
/* fill a few rows if any rooms left */
.wrapper:before {
content:'';
grid-area:3/1/19/2;/* about 15 rows */
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box footer">Footer</div>
</div>
- to use
grid with the right option here on a grid-template-rows (there is no grid-template-area set in your original piece of code):
body {
padding: 20px;
font-family: Helvetica;
margin: 0;
height: 100vh;
/* reference for the direct child */
box-sizing: border-box;
/* include padding and border into size calculation */
}
.wrapper {
display: grid;
grid-template-rows: auto auto 1fr auto;
min-height: 100%;
/*of avalaible space of sized(height:xx) parent */
}
.box {
background-color: #20262e;
color: #fff;
border-radius: 3px;
padding: 20px;
font-size: 14px;
}
.footer {
grid-row: 4
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box footer">Footer</div>
</div>
edit : For an unknown numbers of rows, then flex would be efficient .
body {
padding: 20px;
font-family: Helvetica;
margin: 0;
height: 100vh;
/* reference for the direct child */
box-sizing: border-box;
/* include padding and border into size calculation */
}
.wrapper {
display: flex;
flex-direction: column;
min-height: 100%;
}
.box {
background-color: #20262e;
color: #fff;
border-radius: 3px;
padding: 20px;
font-size: 14px;
}
/* if you need a gap , use margin , a pseudo stands here ! */
.box + .box {
margin-top:2px;
}
.wrapper:after {
content: '';
flex: 1;
}
.footer {
order: 2;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box footer">Footer</div>
</div>