0

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>

JSFIDDLE

Googlebot
  • 14,156
  • 43
  • 126
  • 219

1 Answers1

1

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>
G-Cyrillus
  • 94,270
  • 13
  • 95
  • 118
  • When I open your snippet in full-page, each row is exactly 1/4 of the page height. Do I miss something? The whole point is to keep the height of `a`, `b` and `footer` limited to the height of their contents. – Googlebot May 24 '21 at 11:52
  • if you set a min-height to your grid, it will stretch the rows to fill that height. That is the normal behavior, you need to insert an extra virtueal row than will stretch as much as it can if there is room.@Googlebot I'll update the snippet with an example of the idea. – G-Cyrillus May 24 '21 at 11:54
  • That's the basis of my question: how to place the footer at the bottom of the page without affecting/stretching other rows. I mentioned that `min-height` does not work here. I look for another solution. – Googlebot May 24 '21 at 11:57
  • @Googlebot however, you'll need to manage also the sizing to avoid overflow/offset when not needed. updated your snippet with grid area. using grid-template-rows would be more efficient here. (grid-area is not enought flexible to my taste most of the time, just a personnal opinion). added 2 snippets, to me the last one is the most efficient. – G-Cyrillus May 24 '21 at 12:07