·
2 min read

Sticky Footer in GatsbyJS using Flexbox

Sticky Footer in GatsbyJS using Flexbox Image

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

Unfortunately, I had some struggles solving this, and I 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 friendly solution for the sticky footer problem. It can be used to layout content in a horizontal and vertical direction. So we 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 take up all the available space in the container automatically.

Following, you can see his solution:

<body class="site"> <header>…</header> <main class="site-content">…</main> <footer>…</footer> </body>

The corresponding CSS classes:

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

Take a look at the live demo.

GatsbyJS solution

GatsbyJS is based on React; therefore, we have to think differently.

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;

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 has to be a direct child of the <body> tag, which it isn't due to GatsbyJS's and React's way of building the HTML document.

To solve the problem, I added a new <div></div> tag, which should represent the <body> tag of the example mentioned above.

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;

The CSS:

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

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

Example Website

I hope this post is helpful if you try implementing a sticky footer on a GatsbyJS website.

Happy Coding!

I will never share any of your personal data. You can unsubscribe at any time.

If you found this article helpful.You will love these ones as well.
The 10 Favorite Features of My Developer Portfolio Website Image

The 10 Favorite Features of My Developer Portfolio Website

The Engineering Behind My Portfolio Website Image

The Engineering Behind My Portfolio Website

Rendering Dynamic Markdown in Nuxt 3+ Image

Rendering Dynamic Markdown in Nuxt 3+

Analyze Memory Leaks in Your Nuxt App Image

Analyze Memory Leaks in Your Nuxt App