Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I have a sticky footer with my CSS Grid layout?

Tags:

html

css

css-grid

I found this CodePen solution for a sticky footer in a CSS Grid layout, but it has two problems for me:

  1. It is kinda ugly with min-height: 100% and height: 100%
  2. It only works with two elements in the body (a div and a footer)

I need something that works with this HTML structure:

<body>
    <nav>Some navigation buttons</nav>
    <main>The content</main>
    <footer>Copyrights and stuff</footer>
</body>

I don't really want to pack the <nav> and the <main> into a <div>, and I would love to do this in pure CSS.

// Not required!
// This is just to demo functionality.

$("#add").on("click", function() {
  $("<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>").appendTo(".content");
});
html {
  height: 100%;
}

body {
  min-height: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
}

.content {
  padding: 20px;
}

.footer {
  grid-row-start: 2;
  grid-row-end: 3;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font: 16px Sans-Serif;
}

h1 {
  margin: 0 0 20px 0;
}

p {
  margin: 0 0 20px 0;
}

.footer {
  background: #42A5F5;
  color: white;
  padding: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
  <h1>Sticky Footer with Grid</h1>
  <p><button id="add">Add Content</button></p>
</div>

<footer class="footer">
  Footer
</footer>
like image 625
Mitko Rusev Avatar asked Sep 11 '17 15:09

Mitko Rusev


People also ask

Does sticky work with grid?

If you've ever tried to put a sticky item in a grid layout and watched the item scroll away with the rest of the content, you might have come to the conclusion that position: sticky doesn't work with CSS Grid.

How do I make my grid sticky?

You need to use align-self: start on the thing you want to be sticky . Delete the background: grey from main and see the side effect of your solution: no more equal-height columns, a quite important benefit of CSS Grid. It's an alternate solution, but you're right.


2 Answers

Here is a CSS Grid solution, but it's far better using a class for the target.
Using grid-areas this will be very straight forward:

html, body {
    margin: 0;
    height: 100%;
}
body {
    display: grid;
    grid-gap: 10px;
    grid-template-columns: 1fr;
    grid-template-areas: "nav" "main" "footer";
    grid-template-rows: 100px 1fr 80px;
}
nav {
    background-color: #7E57C2;
    grid-area: nav;
}
main {
    background-color: #F8BBD0;
    grid-area: main;
}
footer {
    background-color: #7E57C2;
    grid-area: footer;
}
<body>
    <nav>Some navigation buttons</nav>
    <main>The content</main>
    <footer>Copyrights and stuff</footer>
</body>
like image 184
Whisher Avatar answered Sep 24 '22 03:09

Whisher


The trick is to use:

min-height: 100vh; grid-template-rows: auto auto 1fr; with...

align-self: end; for the footer.

If we add left/right margins, place the <nav> in a header, add a margin for the footer content and assume another grid for the main content:

body {
    display: grid;
    grid-gap: 1em 0;
    grid: auto auto 1fr / 10vw 1fr 10vw;
    margin: 0;
    min-height: 100vh;
}

header {
    background-color: #7E57C2;
    grid-column: 2;
}

main {
    background-color: #F8BBD0;
    display: grid;
    grid-column: 2;
}
footer {
    background-color: #7E57C2;
    align-self: end;
    grid-column: 2;
    margin-bottom: 1em;
}
<body>
    <header>Some navigation buttons</header>
    <main>The content</main>
    <footer>Copyrights and stuff</footer>
</body>

This has elegant simplicity that previous solutions lack.

With evergreen browsers there is no need to complicate matters.

Previous answers are not as maintainable. Pitfalls include:

  • Forcing header/footer to fixed pixel dimensions.
  • Using grid areas instead of a simpler grid definition. There are bonus points for combining grid-template-rows and grid-template-columns into a one-liner.
  • Extensive 'width/height/min-height: 100%' definitions everywhere on html and body tags. This might have made sense when IE6 ruled the roost but is not needed with modern browsers.
  • Using flexbox layout. This is not the layout engine of the future. CSS grid will be what I want to maintain in five years time.
  • Using pixels and percentages. What is a pixel? Who knows when there are retina screens and high-res phone screens. I used to like pixels but there are other units that make more sense, 'vw/vh/vmin/vmax' plus 'em/rem'. The percentage measurement is on its way out too for CSS grid so best to get out of the habit.
like image 37
Henry's Cat Avatar answered Sep 24 '22 03:09

Henry's Cat