DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Cover image for Sticky Footer in GatsbyJS using Flexbox
Michael Hoffmann
Michael Hoffmann

Posted on • Originally published at mokkapps.de on

Sticky Footer in GatsbyJS using Flexbox

I have recently developed some static websites based on GatsbyJS which have a sticky footer. A sticky footer is always positioned on the bottom of the page, even for sparse content.

Unfortunately, I had some struggle to solve this and I, therefore, want to share my learnings with you.

Non-GatsbyJS solution

In a traditional HTML, CSS, JavaScript application we can use different ways to implement such a fixed footer but I prefer the Flexbox solution of Philip Walton.

Flexbox provides a nice solution for the sticky footer problem. It can be used to layout content in horizontal and vertical direction. So we just need to wrap the vertical sections (header, content, footer) in a flex container and choose which one should expand. In our case, we want the content to automatically take up all the available space in the container.

Following, you can see his solution:

<body class="site">
  <header>โ€ฆ</header>
  <main class="site-content">โ€ฆ</main>
  <footer>โ€ฆ</footer>
</body>
Enter fullscreen mode Exit fullscreen mode

The corresponding CSS classes:

.site {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

.site-content {
  flex: 1;
}
Enter fullscreen mode Exit fullscreen mode

Take a look at the live demo.

GatsbyJS solution

GatsbyJS is based on React and we, therefore, have to think different.

The basic layout.js file from the official GatsbyJS default starter has a similar structure like the following example:

const Layout = ({ children }) => (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => (
      <>
        <Helmet
          title={data.site.siteMetadata.title}
          meta={[
            { name: 'description', content: 'Sample' },
            { name: 'keywords', content: 'sample, something' },
          ]}
        >
          <html lang="en" />
        </Helmet>
        <Header siteTitle={data.site.siteMetadata.title} />
        <div>{children}</div>
        <Footer />
      </>
    )}
  />
);

export default Layout;
Enter fullscreen mode Exit fullscreen mode

So if we would style <body></body> and the <div>{children}</div> as proposed in Philip Waltonโ€™s solution it would not work.

But why? Because it would mean that the <Footer/> component would be included in the <body></body>.

To solve the problem I added a new <div></div> tag which is the equivalent to the <body></body> tag of the above mentioned example.

So my layout.js looks this way:

const Layout = ({ children }) => (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => (
      <>
        <Helmet
          title={data.site.siteMetadata.title}
          meta={[
            { name: 'description', content: 'Sample' },
            { name: 'keywords', content: 'sample, something' },
          ]}
        >
          <html lang="en" />
        </Helmet>
        <div className="site">
          <Header siteTitle={data.site.siteMetadata.title} />
          <div className="site-content">{children}</div>
          <Footer />
        </div>
      </>
    )}
  />
);

export default Layout;
Enter fullscreen mode Exit fullscreen mode

The CSS:

.site {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

.site-content {
  flex-grow: 1;
}
Enter fullscreen mode Exit fullscreen mode

You can see a working example on my GitHub Traffic Viewer website. The first page shows a spare content but the footer is stuck to the bottom. If you sign in and see the result list, the footer is also shown on the bottom of the page.

Example Website

I hope this post is also helpful for you if you try to implement a sticky footer in a GatsbyJS website.

Happy Coding!

Top comments (11)

Collapse
 
tux0r profile image
tux0r

What's wrong with using position:fixed? It can be combined with flexboxes and it does not require JS.

Collapse
 
ardennl profile image
Arden de Raaij

Have you read this? philipwalton.github.io/solved-by-f...

The idea is not fixing the footer, or making it sticky, but to make sure the footer is on the bottom of the viewport even though the entire page is smaller, and of course just have it run it's natural course when the page is larger than the viewport

Collapse
 
equinusocio profile image
Mattia Astorino

Even better position: sticky

Collapse
 
tux0r profile image
tux0r

I did not know that. Thank you, looks handy.

Thread Thread
 
petecapecod profile image
Peter Cruckshank

Yeah with flexbox and CSS grid you can't use position: fixed;
You use position: sticky;

Collapse
 
gabiduarte profile image
Gabrielle Duarte

Thank you SO much! I've been trying everything to get the sticky footer to work on gatsby!

Collapse
 
darryl profile image
Darryl Young

Thanks for sharing, Michael! While I'm using Next.js and not Gatsby, I had basically the same problem and this led me to the solution. Thanks again.

Collapse
 
rajssj4 profile image
Rajesh Nautiyal

thanks, this is helpful

Collapse
 
diveafall profile image
David Isayan

Thank you so much for taking the time to share this with us. You saved me a lot of time. Thanks again!

Collapse
 
ronancodes profile image
Ronan Connolly ๐Ÿ› 

Genius!
This is so simple and works a treat.

Collapse
 
alsoknownasdrew profile image
Andriy Frankevych

Great! You just saved me quiete some time, thank you!

Timeless DEV post...

How to write a kickass README

Arguably the single most important piece of documentation for any open source project is the README. A good README not only informs people what the project does and who it is for but also how they use and contribute to it.

If you write a README without sufficient explanation of what your project does or how people can use it then it pretty much defeats the purpose of being open source as other developers are less likely to engage with or contribute towards it.