Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am building a landing page where the user first sees a main area with a footer underneath it. Scrolling further down reveals that the footer is a sticky header, and I aim to use pure CSS to achieve this. To obtain the fullscreen appearance of the main content and the footer I set the height property to two different values: 92% and 8% (using vh also doesn't work). No matter the height I specify in my CSS (different units and all), my footer div is not sticking. As soon as I remove the height property it works as intended.

Here is a screenshot of my page before removing the height properties:

As you can see, it does not stick:

After removing the height property values, it does stick:

Below the relevant code:

html,
body {
  height: 100%;
  margin: 0;
#main {
  height: 92%;
#landing {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
#landingContent {
  width: 20vw;
#footerNav {
  height: 8%;
  display: flex;
  align-items: center;
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
<div id="main">
  <div id="landing">
    <div id="landingContent">
      <h1 class="logo">Logo</h1>
      <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
      <button>Button</button>
<div id="footerNav">
  <div id="footerNavContent">
    <h1 class="logo">Logo</h1>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>
<p>Hello</p>

I have read that using the overflow property can be problematic, though it is is not present nor have I heard anything about height being an issue for others. I might be wrong, of course.

I have tested on:

  • Firefox 61 (Nightly)
  • Safari 53 (Tech Preview)
  • Chrome 65
  • EDIT: Big development; removing the height property from #main keeps #footerNav sticky.

    There's not much difference in height of footer in your first (loading page with set height) screenshot and third (working without height) screenshot. So, what specific purpose do you want to set the height of the footer for? Also, have you tried removing height only for the footer? – xuhaib Apr 16, 2018 at 1:20 @xuhaib I appreciate having the set height for uniformity and to assure the page is 100% filled with the footer and main content, if that makes sense. Removing the height from the footer produced an interesting result: the footer stays sticky for a little but, but then 'unsticks' once I've scrolled past a certain point. Tested in Firefox. – Lachlan Apr 16, 2018 at 1:22 Completely disagree, CSS3's 'sticky position property' is made for the problem he is trying to solve. Temani hit the nail on the head. – JΛYDΞV Dec 28, 2019 at 22:14

    The issue here is with height, but not the height you thought about. Let's first start by the definition of the sticky position:

    A stickily positioned element is an element whose computed position value is sticky. It's treated as relatively positioned until its containing block crosses a specified threshold (such as setting top to value other than auto) within its flow root (or the container it scrolls within), at which point it is treated as "stuck" until meeting the opposite edge of its containing block.

    The important part here is the last sentence which explain that the position sticky will end when the element reach the edge of its containing block and in your case the containing block of the sticky element is the body and you set the body to be height:100% and you are having an overflow of content.

    So when setting the height of main to be 92% and the footer to be 8%, you already made the footer at the oppsite edge of its containing block. Here is an illustration where I added a background color to the body so you can clearly see this:

    html,
    body {
      height: 100%;
      margin: 0;
    html {
      background:white;
    body {
      background:blue;
    #main {
      height: 92%;
    #landing {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
      text-align: center;
    #landingContent {
      width: 20vw;
    #footerNav {
      height: 8%;
      display: flex;
      align-items: center;
      position: sticky;
      top: 0px;
      background:red;
      color:#fff;
    
    <div id="main">
        <div id="landing">
            <div id="landingContent">
                <h1 class="logo">Logo</h1>
                <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
                <button>Button</button>
    <div id="footerNav">
        <div id="footerNavContent">
            <h1 class="logo">Logo</h1>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>

    As you can see the logo is already at the bottom of the body so there is no way to make it move as sticky. Also your content is overflowing.

    Now if you decrease the height of the main content a bit, you can see a small sticky behavior that will end when the footer will reach the bottom of the blue part (the body).

    html,
    body {
      height: 100%;
      margin: 0;
    html {
      background:white;
    body {
      background:blue;
    #main {
      height: 82%;
    #landing {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
      text-align: center;
    #landingContent {
      width: 20vw;
    #footerNav {
      height: 8%;
      display: flex;
      align-items: center;
      position: sticky;
      top: 0px;
      background:red;
      color:#fff;
    
    <div id="main">
        <div id="landing">
            <div id="landingContent">
                <h1 class="logo">Logo</h1>
                <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
                <button>Button</button>
    <div id="footerNav">
        <div id="footerNavContent">
            <h1 class="logo">Logo</h1>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <p>Hello</p>
    <div id="landingContent"> <h1 class="logo">Logo</h1> <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p> <button>Button</button> <div id="footerNav"> <div id="footerNavContent"> <h1 class="logo">Logo</h1> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p>

    Related questions for more details/examples:

    Why element with position:sticky doesn't stick to the bottom of parent?

    What are `scrolling boxes`?

    If you specify `bottom: 0` for position: sticky, why is it doing something different from the specs?

    I had the same issue, but I needed the height: 100%; on the parent container. In my case I have a sticky navigation, the content needs to grow to its full length and the footer should always be visible at the end of the page (but with no position attribute).

    I fixed it by setting overflow: auto; to that parent container. Now the parent is still 100% tall but the sticky container inside it, doesn't matter the height limitations.

    The support for the use of position: sticky seems to be sort of weak. You can check that in this page:

    https://caniuse.com/#search=position%3A%20sticky

    If you want a sticky footer, you may use position: absolute, which is supported by every browser. I took your code and created like a mini version of it to illustrate my point regarding position: absolute.

    <!doctype html>
        <style>
                margin: 0;
                padding: 0;
            .footerNav {
                background-color: red;
                position: absolute;
                bottom: 0;
                width: 100%;
                height: 100px;
        </style>
    </head>
        <div id="main">
            <div id="landing">
                <div id="landingContent">
                    <h1 class="logo">Logo</h1>
                    <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
                    <button>Button</button>
        <div class="footerNav">
            <div id="footerNavContent">
                <h1 class="logo">Logo</h1>
    </body>
    

    Please, notice that I changed id="footerNav" for class="footerNav". I personally favor classes for applying styles. But you can use ids if you still prefer to.

    If you want the login page to appear, and then the user to scroll a little bit to see your footer, then you can use the height: 100vh and remove the position absolute from the footer since it will be pushed down below by the main content div. For instance:

    <!doctype html>
        <style>
                margin: 0;
                padding: 0;
            #main {
                height: 100vh;
            #footerNav {
                background-color: red;
                position: relative;
                bottom: 0;
                width: 100%;
                height: 100px;
        </style>
    </head>
        <div id="main">
            <div id="landing">
                <div id="landingContent">
                    <h1 class="logo">Logo</h1>
                    <p id="landingParagraph">Lorem ipsum, paragraph content, etc etc.</p>
                    <button>Button</button>
        <div id="footerNav">
            <div id="footerNavContent">
                <h1 class="logo">Logo</h1>
    </body>
                    Thanks for the response, but I don't think you've really answered my question: the 'sticky' behaviour works but when the height properties for the two divs is applied it breaks.
    – Lachlan
                    Apr 16, 2018 at 5:33
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.