One Line - Sticky Header using CSS
Tags: beginners, css, tutorial, webdev
Published: 2020-08-04 12:44:50

How many times have we come across a situation where you want the header of a website to remain on top of everything even if you scroll past it. 

Or, to have a navigation bar that is beneath a hero-banner to stick to the top once we scroll past it.

Or even for a navigation bar to stay at the bottom of a mobile website.

![I know](https://media.giphy.com/media/XZ0yPco3eynUAGU0i3/giphy.gif)

We have been in this **sticky situation** _(pun intended)_ over and over. The time has come we solve this once and for all. 

The best part is, we will do it in one-line 😎

## CSS
```css
nav {
    position: sticky; top: 0;
}
```

I know what you are thinking, that is two lines! OK I admit I got carried away with the one-line heading, but I assure you it is still awesome 😍

Let's see some demo's and understand how it works

**Demo 1:** The nav-bar that just sticks

{% codepen https://codepen.io/akhilarjun/pen/gOrYyzZ %}

Let's try and understand what is happening here.

The markup I have used is pretty simple
<br />
### HTML
```html
<body>
  <nav>
    <ul>
      <li><a href="#first">First</a></li>
      <li><a href="#second">Second</a></li>
      <li><a href="#third">Third</a></li>
    </ul>
  </nav>
  <section id="first">First Section</section>
  <section id="second">Second Section</section>
  <section id="third">Third Section</section>
</body>
```

### CSS
```css
html {
  margin: 0;
  padding: 0;
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body nav {
  position: sticky;
  top: 0;
}
ul {
  width: 100%;
  display: flex;
  justify-content: flex-end;
  box-sizing: border-box;
  padding: 20px;
  background: #fff;
}
li {
  list-style: none;
  margin-right: 20px;
  font-size: 25px;
  font-weight: bold;
}
li a {
  text-decoration: none;
  color: #1ac;
}
section {
  height: 100vh;
  display: grid;
  place-items: center;
  font-size: 50px;
  font-weight: bold;
  background: #eee;
}
```

Of all that mark-up the most important two lines where all the magic happens is
```css
...
body nav{
    position: sticky;
    top: 0;
}
...
```

What it tells the browser is to stick this element to the viewport when its top position value is 0;

An element with `position: sticky;` is positioned based on the user's scroll position.

A sticky element toggles between `relative` and `fixed`, depending on the scroll position. It is positioned relative until a given offset position is met in the viewport - then it "sticks" in place (like `position: fixed`).

Now that we understood how it works let us see two more use-cases of `sticky`.

**Demo 2:** Nav-bar below a hero banner.
{% codepen https://codepen.io/akhilarjun/pen/GRZKaga %}

Here, the nav-bar is below the hero banner. So it acts `relative` until its offset from the top is not 0. The moment the offset value reaches 0 it sticks to the top of the viewport.

**Demo 3:** Application with a sticky header and footer
{% codepen https://codepen.io/akhilarjun/pen/xxVKNgJ %}

Notice how we have styled `footer` element. 
```css
footer {
    ...
    position: sticky;
    bottom: 0;
    ...
}
```

There you go! We are now officially sticky! 🐱‍👤✌

Do you know what else is sticky? Coffee spilled on a table! My days are fueled with coffees and only coffees. So I know, you know what we all should do 🤞
<br />
[<img src="https://cdn.buymeacoffee.com/buttons/lato-orange.png" alt="Buy Me A Coffee" height="51px" width="217px">](https://www.buymeacoffee.com/akhilarjun)

## Keep Hacking ☕

### References
- [Awesome Demos and cool read](https://developers.google.com/web/updates/2017/09/sticky-headers)
- [Can I use `position: sticky`?](https://caniuse.com/#feat=css-sticky)
- [w3Schools](https://www.w3schools.com/howto/howto_css_sticky_element.asp)