Reputation: 15683
I want to place the footer at the bottom of the layout page (when the height is shorter than the window). It is commonly mentioned that the solution is min-height:100vh
, but this expands the height of other elements too. I want to limit the height of all rows limited to the height of their contents while the footer is pushed at the bottom (whenever it is necessary).
body {
font-family: Helvetica;
}
.wrapper {
display: grid;
grid-template-columns: auto;
min-height:100vh;
}
.box {
background-color: #20262e;
color: #fff;
border-radius: 3px;
padding: 20px;
font-size: 14px;
width:100%;
}
.a {grid-area: 1/1/2/2;}
.b {grid-area: 2/1/3/2;}
.footer {grid-area: 4/1/5/2;}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box footer">Footer</div>
</div>
Upvotes: 0
Views: 794
Reputation: 106048
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.
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
.
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>
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>
Upvotes: 2