HTML & CSS Tutorials

CSS Fixed Sticky Header – The Right Way Without JavaScript

Raja Tamil
HTML & CSS

Learn how to make a header fixed sticky to the top and scroll the body content using CSS calc() function without JavaScript like the screenshot below.

HTML Markup

The simple HTML markup has a main element.

It has two children elements inside:

  • header
  • ul list
<main>
  <header>Header</header>
  <ul id="list"></ul>
</main>

Add some style to the header and li which will be added dynamically inside the ul tag using JavaScript.

Note: You could add HTML content directly inside instead of using JavaScript…but I do not want to create a li element 30 times.

CSS

* {
  margin:0;
  padding:0;
  box-sizing:border-box;
}

header {
  width:100%;
  background:#32bacf;
  height:60px;
  font-size:1.4em;
  display:flex;
  align-items:center;
  justify-content:center;
}

li {
  border:1px solid #ececec;
  padding:20px 10px;
  font-size:1.1em;
}

Add List Items Using JavaScript

Get a DOM reference to the ul element using its id list.

Loop through a few times so that we have enough content that will go beyond the height of the browser’s viewport.

Append li to the ul.

Pretty straight forward.

const list = document.getElementById('list');

for(let i = 0; i < 31; i++) {

  const listItem = `
       <li>
          ${i}
       </li>
  `
  list.innerHTML += listItem;  

}

And the final output will look like this.

Make Header Fixed Using Calc()

At this stage, when you scroll vertically the header moves with the content.

To make the header fixed, make the ul content element to take the full height of the viewport minus the height of the header element.

Luckily, we can do dynamic simple calculations using CSS calc() functions without JavaScript.

To get the dynamic height, call the calc() function as a value of the height property inside the ul CSS rule.

Then, get the full height of the ul content element using 100vh which is one of the ways to make a div full screen vertically and horizontally.

Also, get the height of the header from the header CSS rule.

In this case 60px and subtract the height of the header from the height of the ul content element which takes the full height of the screen.

This will push the ul content down, sitting just beneath the header element. Also it takes the rest of browser’s viewport height.

At this stage, the content is overflowing, so enable scrolling by adding the overflow:scroll property to the ul content element.

ul {
  height: calc(100vh - 60px);
  overflow:scroll;

  height: -o-calc(100vh - 60px); /* opera */
  height: -webkit-calc(100vh - 60px); /* google, safari */
  height: -moz-calc(100vh - 60px); /* firefox */
} 

Try it out!

See the Pen Fixed Sticky Header JavaScript by Raja Tamil (@rajarajan) on CodePen.