DEV Community

Akash Deshpande
Akash Deshpande

Posted on • Originally published at akashdeshpande.hashnode.dev

How to: sticky top nav-bar (HTML + CSS)

A common CSS newbie issue we face is, how to code a sticky top bar. This could be the nav-bar, a quick contact bar, quick access bar, etc. Let's assume we want to build a top nav-bar. So the requirements are:

  • Nav bar should be on top
  • It should stick to the top of the page
  • It should scroll with the page

Before we begin, there are some things you should know, they are:

  • Basic knowledge of HTML
  • Basic knowledge of CSS

Excited to learn? Let's jump in!

1. Basic code block

To make a sticky nav-bar, let's build a nav-bar first. We will use header tag for this. For the rest of the content, we will use main tag.

  <header>
  </header>

  <main>
  </main>
Enter fullscreen mode Exit fullscreen mode

2. Let's customize a bit with CSS

/* CSS */
/* imports */
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;900&display=swap');

body{
  padding: 0;
  margin: 0;
  font-family: "Lato", sans-serif;
}

header {
  height: 80px;
  background-color: #eee;
}

Enter fullscreen mode Exit fullscreen mode

In the code above, we've added styling for body, header and main. We've also imported Lato font (because I love sans-serif fonts ๐Ÿ˜).

Body tag

We remove margin and padding on body because when an element takes full width, default padding and margin of body interferes with the full width of the element, in this case, header tag.

Header tag

We add a static height of 80px to the header, and change its color to #eee to differentiate it with rest of the content.

Let's add some content to the header/nav-bar. Generally, nav-bar has a logo and some nav-links. Logo would have an image of some sort, but for ease of the tutorial, we will just replace it with text.

HTML Part:

<header>
  <div class="logo">
    Logo
  </div>
  <ul class="nav-links">
    <li>
      <a href="https://akashdeshpande.hashnode.dev/">Blog</a>
    </li>
    <li>
      <a href="https://www.twitter.com/akashd1995">Contact</a>
    </li>
  </ul>
</header>

<main>
</main>
Enter fullscreen mode Exit fullscreen mode

CSS Part:

/* imports */
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;900&display=swap');

body{
  padding: 0;
  margin: 0;
  font-family: "Lato", sans-serif;
}

header {
  /* general styling */
  height: 80px;
  background-color: #eee;

  /* display part */
  display: flex;
  align-items: center;
  padding: 0 32px;
  justify-content: space-between;
}

.logo {
  font-size: 32px;
  font-weight: 900;
  color: #333;
}

.nav-links li {
  list-style: none;
  display: inline;
  padding-left: 32px;
}

.nav-links li a {
  color: #333;
  text-decoration: none;
}

.nav-links li a:hover {
  color: #ccc;
}
Enter fullscreen mode Exit fullscreen mode

So far, we've added Logo, nav-links and customized them, so that they are in one line and horizontal.
Important part here is the CSS display part in header. We've used display: flex and justify-content: space-between. This places the logo and nav-links at the start and end of the container (header in this case) respectively. If you have not learned CSS flexbox so far, no worries, but it sure is a good thing to have in your skill set.

If we add more content to the page, the nav-bar will scroll with the page, we want it to stick to the top at all times. We will do this in the next part. The next part is important, it contains the magic ingredient that makes it all work.

3. Add the magic ingredient

/* Add this to header CSS */
position: fixed;
width: 100%;
box-sizing: border-box;
top: 0;
Enter fullscreen mode Exit fullscreen mode

Adding position: fixed to header's CSS makes the header stick to the top. We are basically done at this point, but it doesn't look good. The header's width has shrunk, so we will add width: 100%. With this code addition, comes another issue, the width of header goes outside the page. We could technically fix this by adjusting the width %, but we have a better solution. Adding box-sizing: border-box to the CSS limits the width of header to 100% of the viewport, so it spans the whole width of the screen. A precautionary measure we could take here, although it won't be necessary, would be to add top: 0. This is just so that our nav-bar stays at the top of the page.

4. Fix code

We've completed the main step, so what remains? It is the issues we brought with our code. Let's solve those.

Main tag

The main tag contains the rest of the page. When we put position: absolute to header's CSS, the main now takes up the whole page. This means that main will also include the area behind the nav-bar. Since that area won't be visible, we will add padding-top: 80px, the same as the height of the header to main's CSS.

main {
  padding-top: 80px;
}
Enter fullscreen mode Exit fullscreen mode

5. Done!

We have successfully completed our sticky top nav-bar! If you'd like to see it in action, see the codepen here.

Top comments (0)