Googlebot
Googlebot

Reputation: 15683

How to place footer at the bottom of the grid without changing the other rows?

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

Upvotes: 0

Views: 794

Answers (1)

G-Cyrillus
G-Cyrillus

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.

  • 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>

Upvotes: 2

Related Questions