Footer staying on bottom and links

I’m half way through the learn how to build websites course and have been battling with the Web Design System project.The trouble I had was the footer was half way up the page, despite the page being very long. I researched online only to find several methods such as Grid, Flexbox and negative margins.

Even though I may be jumping the gun, I decided to try Flexbox. I created a test page. It only works if I duplicate in the footer position:relative and top:100px which I have on main.

Would Flexbox be the way to go and is this a correct assumption?

Also, when linking to a different section of the page, it doesn’t reach it’s exact location. Only when I have all the positioning (fixed and relative) and top value removed it somehow reaches the destination. I have a link in footer to go to first sentence.

How can I resolve the link going to the correct place?

HTML:

<body>
    <header>
        <h1>This is a Test Page</h1>
    </header>
    <main>
        <p id="top">This is a test first paragraph on this page.</p>
        <div class="boxes">
            <p>Box 1</p>
        </div>
        <div class="boxes">
            <p>Box 2</p>
        </div>
        <div class="boxes">
            <p>Box 3</p>
        </div>   
    </main>
    <footer>
        <div class="foot">
          <ul>
            <li><a href="#top">Home</a></li>
            <li>&#169; Test Page</li>
          </ul>
        </div>      
    </footer>  
</body>

CSS:

html {
    height: 100%;
}

body  {
    box-sizing: border-box;
    background-color: aqua;
    font-family: Arial, Helvetica, sans-serif;
    margin: 0;
    display: flex;
    flex-direction: column;
    min-height: 100%;
}

h1  {
    text-align: center;
}

header {
    width: 100%;
    background-color: pink;
    position: fixed;
    z-index: 1;
}

main {
    margin: 30px auto;
    width: 40%;
    position: relative;
    top: 100px;
}

.boxes {
    margin: 40px auto;
    width: 250px;
    height: 250px;
    border: 1px solid gray;
}

.boxes p {
    text-align: center;
}

footer {
    margin-top: auto;
    width: 100%;
    background-color: lightcoral;
    text-align: center;
    position: relative;
    top: 100px;
}

footer li {
    display: inline-block;
}

.foot {
    margin: 0;
    padding: 30px;
}

From looking at your CSS, you’ve worked out how to have a header section stick to the top of your page. How can you apply this same method to have a footer stick to the bottom? :slight_smile:

(It doesn’t rely on flexbox, btw.)

I presume you’re referring to the anchor element <a href="#top">Home</a> which targets the fragment with ID top?

I’m also guessing that your problem is that where you’re wanting the page to scroll to ends up behind your fixed header?

When I created a position: fixed for my header, I realised it behaves like absolute with my content below partially being covered up. Hence, creating position:relative and top:100px for my main tag.

I wanted the footer to show up at the bottom as I scrolled down. Originally, I tried flexbox because the main content was covering the footer which wasn’t at the bottom. I’ve removed flexbox now, but kept the position:relative and top:100px in footer…and it works! :smiley:

Can I assume any main container with positioning values, you have to duplicate in the footer?

When I click on the link, it doesn’t reach as far up as desired. It goes to the next line of code down. It’s only when I experiment by removing the position:fixed in the header, the link goes exactly to where I expected it to.

I was wondering if this is because I have position:fixed in my header and possibly position:relative and top:100px in my main tag. If it is the case, what would you recommend to resolve this problem?

Yes, using position: fixed and a z-index: 1 results in your header being stuck to the top of the page and it displaying over the other content. Adding margin to the top of the obscured content is how I’d have fixed that. :slight_smile:

I’m not entirely sure what you mean here. If you mean you wanted it to appear at the bottom, so that it’s shown in the flow of the page as you arrive at the bottom, then that happens already with the code as it stands.

If you mean you wanted it stuck to the bottom, much like your header is stuck to the top, then you already know how to do that. (You’ve done it with your header already.)

If you mean something else, well, you’ll need to tell me what you mean. :slight_smile: (Feel free to wireframe the blocks of your site in Paint or something if that’ll make it clearer. :slight_smile:)

No, it goes to exactly where you’re telling it to.

Your #top fragment is the paragraph tag:

        <p id="top">This is a test first paragraph on this page.</p>

If I change your stylesheet to include opacity: 40% in the header ruleset, you can see where the anchor takes the page to when I click the link targeting the #top fragment:

See how at the very top of the page, your paragraph is there? Normally, with the header section fully opaque, you would not be able to see it.

Yes, I think so.

Clicking that anchor puts the targeted fragment right at the very top - behind the header section, which is statically fixed to the page.

Using the Dev Tools, I can see that your header element is roughly 80 pixels in height:
image

The problem that you need to work around is that, essentially, you need to add at least 80 pixels of margin to the location that your anchor is linking to.

We can do this with a bit of CSS, by using the ::before pseudo-element:

#top::before {
  display: block;
  content: " ";
  margin-top: -100px;
  height: 100px;
  visibility: hidden;
}

What we’re doing with this CSS is creating a pseudo-element which exists in the flow of the page before the #top element, which is 100 pixels high. This effectively pushes the paragraph tag down by 100px, but that looks a bit weird… so the negative margin (of -100px) moves it back to where it originally would have been.

However, when we click the link, because we’ve created a ::before pseudo-element that is part of the #top element, it’s the top of this pseudo-element which gets hoisted to the top of the browser window. The actual paragraph of text remains visible, below the header section.

Here I have selected the p element with the ID #top; notice how it’s quite a bit larger than the paragraph element, which is still visible below the header (which is still at 40% opacity):

Hopefully that solves some of your problems!

If you’re still stuck with the footer, please let us know how it’s not doing what you want (and what it is that you want it to do) and we’ll try and help. :slight_smile:

1 Like

Thank you @thepitycoder for a in depth reply. I now fully understand!

1 Like

No worries. Let us know if you get stuck with anything else. :smiley: