Search code examples
htmlcssflexboxgatsby

Footer stuck in middle only when there is little content


I know the title is a known 'issue'. However, I have tried many solutions, but none seem to work.

My footer is stuck on the bottom (phew) on almost all cases (when there is a lot of content, when I can scroll,..). Sadly, when there is barely any content, it just goes straight to the middle. I really have no clue why this is happening :( I am using Gatsbyjs for my website.

This is the global.css

html {
  height: 100%;
}

main {
  flex: 1 0 auto;
}

body {
  display: flex;
  flex-direction: column;
  position: relative;
  height: 100%;
  margin: 0;
  font-family: "Roboto", sans-serif;
  color: whitesmoke;
  background: radial-gradient(circle at center, #2b2b2b, #414141);
}

My footer.js component and it's css is:

css:

footer {
  background-color: #2b2b2b;
  position: relative;
  font-size: smaller;
  opacity: 0.98;
  padding: 1rem;
  width: 100%;
  margin-top: auto;
}

html for footer:

 const Footer = () => {
  return (
    <div>
      <footer>
        <p>©Copyright {currentYear} Humital - Made with ❤️</p>
      </footer>
    </div>
  )
}

export default Footer

the main html comes from layout.js:

<div className={styles.flex}>
    <NavBar />
    <div className={styles.container}>
      <main>{children}</main>
    </div>
    <Footer />
  </div>

Which holds some css for the container:

    .container {
  display: flex;
  flex-direction: column;
  padding-top: 5rem;
  padding-bottom: 1rem;
  margin-left: 1rem;
  line-height: 1rem;
  flex: 1 0 auto;
  position: relative;
}

.flex {
  flex: 1;
}

Not sure why the footer won't go down when there is no content :( Any help is welcome! :)


Solution

  • I think you just need to add min-height: 100vh rule (and a flex-direction) to your .flex class:

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

    Because your .container has the flex: 1 0 auto will push the footer to the bottom.

    Summarizing, you only need this rules to stick your footer to the bottom:

    .flex { 
      display: flex;
      flex-direction: column;
      min-height: 100vh;
    }
    
    .container {
      flex: 1 0 auto;
    }
    

    .flex applies to the outer wrapper, which contains the Footer, the <main> and the <NavBar />.

    .container applies to the <main> or the <main>'s wrapper. I think it's not needed to wrap the <main> with another <div>, you can apply the styles directly to the <main> tag, yet the approach to push the footer to the bottom is exactly the same.