sticky header tutorial feature image

How to create a sticky website header

Abbey Fitzgerald's Layout avatar

Website headers that stay in place when a user scrolls have become a very popular design element. They allow the user to easily access the navigation without the need to scroll up each time they want to choose a different page or option.

Elements with this functionality are often called “sticky” because they stick and remain visible as the user moves through the website. When a user first arrives at the website, elements will be in their starting position, but then the sticky header will remain in the same place.

Since navigation is one of the most important elements of a website, taking this approach helps make the navigation more accessible. Having a navigation that stays in place allows for an easy flow for the user as they move through the website content, which is extremely important.

“Sticky navigation elements help create an easy user flow as people move through your website. ”


What makes it sticky?

Fixed positioning is a key component to getting the navigation to stay in place. This fixed position element is positioned relative to the viewport, or the browser window itself. Because the viewport doesn’t change when the site is scrolled, this fixed positioned element will stay in the same place when the page is scrolled.

A screenshot of Local by Flywheel

Note: Don’t try this on your live site

Remember: You should never change the code directly on your site, to ensure nothing breaks. Our free local development app, Local, will help you set up a test environment where you can safely follow along this tutorial.

How do we get the navigation to stay in one place?

Making the navigation sticky could not be easier; it’s just done with CSS styling. It basically looks something like this:

.navbar-fixed-top {

position: fixed;

right: 0;

left: 0;

z-index: 999;


No matter how long your page is, or how many times you scroll up and down, the nav will be “stuck” to the top of the page. A class called .navbar-fixed-top was added to the navigation that creates the placement for the navigation. I added this class to the nav tag. The position is set to fixed and adding left and right positioning ensures that the placement is correct and takes up the full width of the page.
Keep in mind, anytime this class is applied, it will create the fixed position of the element. Most likely this class will only be applied once, otherwise there would be multiple page elements behaving the same way in the same place, creating a jumbled mess.

Another important consideration is the z-index. Because we want the navigation to always be visible, we need to make sure it does not get overlapped by other elements. When we reference the z-index, we are talking about the CSS property that sets the stack order of specific elements. An element with greater stack order is always in front of another element with lower stack order. A value of 999 is a large number, making it a safe bet for the navigation.

Adjust page body

Because the navigation is now at a fixed position, it will cover part of the content at the top. There is a simple fix for this. Adding padding to the top of the body will push the page down so then content at the top will not be covered by the header when the user arrives on the page.
You can add padding to the body in your CSS file:

body {

padding-top: 75px;


Keep in mind that your padding may be larger or smaller depending on how thick the fixed header is.

Not sold on the sticky site header? Learn how to add a sticky back-to-top button to your site.

Making the sticky header squishy

It’s common to find a header that becomes thinner when a user scrolls past a certain point, making it look squishy. When the navigation decreases in size, it helps give the user more space to see the main website content. This is particularly helpful on smaller devices. We will be using a combination of CSS and JavaScript to make this happen.

Squishy navigation with AnimatedHeader script

To add an animated header that will change its size on scroll, there is a great, lightweight solution to make the navigation squishy. It is called AnimatedHeader. It has an MIT license, so it can be used for personal or commercial projects. To get these files, check out AnimatedHeader on GitHub.


Basic CSS for navigation

Let’s take a look at two important CSS styles. The first probably looks familiar to you, .navbar-fixed-top which specifies our height, width, and fixed position for the sticky navigation. Below, you can see there is another class added that specifies a height of 75px. This is the “squished” size.

.navbar-fixed-top {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #f6f6f6;
z-index: 999;
height: 90px;
overflow: hidden;
-webkit-transition: height 0.3s;
-moz-transition: height 0.3s;
transition: height 0.3s;

.navbar-fixed-top.cbp-af-header-shrink {
height: 75px;

To change the size, JavaScript is used to add the class of .cpb-af-header-shrink. Let’s take a look at the part of the script that makes this happen:

function scrollPage() {
var sy = scrollY();
if ( sy >= changeHeaderOn ) {
classie.add( header, 'cbp-af-header-shrink' );
else {
classie.remove( header, 'cbp-af-header-shrink' );
didScroll = false;

Just a reminder, there is more to the script, so be sure to download the source code so you have all the components. As you can see, after a user scrolls past a certain point, the class of .cpb-af-header-shrink is added. If the user scrolls back up the page, this class is removed.

The CSS sticky positioning option

There’s also an option that may be less hassle. Depending on the browser support you are designing for, position: sticky; makes creating a sticky header very simple. Browser support isn’t terrible, but it’s not fully global either. When you have sticky declared, prefixes may be used. Check out Can i Use for more details.

A simple way to describe sticky positioning is that it is a combination of relative and fixed positioning. I’m guessing you come across sticky positioning quite a bit. We’re talking headers here, but it’s also useful for any UI element that you want to be “sticky” as users are scrolling. They see it get “stuck” it when element gets to a specific distance from the edge of the viewport.

The element is treated as relative positioned until it hits a certain point and then it is “fixed.” This point is declared by using CSS. The “point” is basically when you specify top, bottom, left, or right, like you would with absolute positioning. You need to specify so the element has something to “stick” to.

Using position: sticky

It’s pretty simple to use. A few CSS declarations and I was able to have a sticky header. Here are three simple steps:

  1. Find the correct style so you can declare the element as sticky using position:sticky; (don’t forget browser prefixes like position: -webkit-sticky;).
  2. Choose the “sticky edge” (top, right, bottom, or left) for the item to “stick” to.
  3. Declare the distance from the “sticky edge,” i.e. 10px for a header that becomes sticky when it is 10px away from scroll area.
.navbar-fixed-top {
  position: -webkit-sticky;
  position: sticky;
  top: 0;

sticky header css positioning example

I didn’t want any space between the sticky header and the viewport, so it’s 0 pixels from the top. You can see this example on Codepen.

Sticky overflow situations to be aware of

Overflow compatability

It’s great, but it’s not perfect. There are some limitations. Overflow can sometimes be a little unpredictable. It’s best to stay clear of certain types of overflow on a parent element with something that needs position: sticky. There can be issues with overflow auto, scroll, or hidden.

Limited browser support

Browser support is limited, so using the supports rule to detect if the current browser supports sticky positioning is an option. That looks like:

    position: -webkit-sticky;
    position: sticky;
    top: 0;

It’s important to think about if the sticky positioning is absolutely necessary. If it is, the fixed positioning approach can be used. If it is not absolutely necessary, or browser support is not a concern, the sticky approach is easier to implement.

It may seem complex at first, but there’s no reason to be stuck in a navigation rut; it’s relatively simple to make your navigation sticky and squishy. With some simple CSS fixed positioning, you can easily create a sticky website header. With some simple JavaScript, the fixed navigation can be enhanced by squishing down to a reduced height, giving users more room to view website content.

Don’t try this on your live site

Create a sticky website header while your site’s on Local! Learn more and download it for free here!

This article was originally published on February 2nd, 2016. It was last updated October 14th, 2018.

Comments ( 12 )

  1. Richard

    December 6, 2018

    An option to hide or toggle it on/off would be good rather than denying the user a choice over their screen area that they once had in the absolute position whether they want it there or not. For those it distracts they to have rely on element hiders and extensions to manage it.

    It was never problem for me when they were not in a fixed position and now they have become such a nuisance when unwanted and they go past helpful. They can be very distracting when they span at the top and I find I don't need them quick enough for it to be stuck there constantly and the in way.

    They say it is in the name of "modern web design" and it is an "improvement" but restricting the content that I only want to see or cutting parts of my screen area with things that maybe unwanted is hardly an improvement. Assuming the user will like it because it is quicker to navigate without a choice is no different to putting words in their mouths.

    It is nothing new. It started out with aggressive advertising over 10 years ago when advert banners use to all spammy things like interfere and stick other things over webpages that don't belong there and make fake fixed browser alert bars like that yellow one targeted for Firefox back then and there was the dodgy browser toolbar epidemic and now they are in the form of these things.

    On DuckDuckGo they do have one that you can adjust in settings, appearance, Archive has one you can close, Cisco and Google maps have left side pane to toggle on/off so at the least user has a choice over their screen area.

  2. Joel

    September 27, 2018

    I tested this on IOS 12 and IOS 11, and the sticky doesn't seem to be working.

  3. Dan Jacobson

    August 27, 2018

    I hate this trend.
    It eats up 20% of webpages on my screen and leaves the user scrolling in tunnelvision.

  4. Shina

    July 14, 2018

    I just tried this header code on my website and it looks awesome.. Thanks Abbey!

  5. Johny Why

    June 27, 2018


    i noticed that, on this page on your website, you have a header ad that says "Have you tried Flywheel? Join the best designers and creative agencies in the world."

    if i page down, then part of the page content gets lost behind the advert. The bit of text that's below the screen before i page down lands behind the advert after i page down.

    Would that be fixed by .body{padding-top:...} ?


  6. Geekolive

    June 9, 2018

    Really informative post. I was searching for same. I watched many videos on youtube but there was none like this informative post. Really helped me a lot.

  7. Keerthan

    March 30, 2018

    Thank you for the in-depth guide Abbey.

  8. Riyad

    February 18, 2018

    z-index: 999 in my CSS was important to note. Thanks for the comprehensive article. Came and found just what I needed to make my sticky navbar stay above the other elements on my webpage (z-index)!

  9. Areeba Mahmood

    December 14, 2017


  10. Jessica

    September 22, 2016

    Hi there,
    I would like to add this sticky header to all my pages but I am a novice. Where do I start (and I mean from the very beginning)? :-)
    I have downloaded the files AnimatedHeader
    I have theme Opportune Pro in Wordpress
    Thanks a million!

  11. Michael

    February 4, 2016

    I style for this in my css-

    .logged-in .navbar-fixed-top {
    top: 32px;

    /* Fix the top margin when logged in */
    @media screen and (max-width: 782px) {
    .logged-in .navbar-fixed-top {
    top: 46px;

    /* Fix the top margin when logged in */
    @media screen and (max-width: 600px) {
    .logged-in .navbar-fixed-top {
    top: 42px;

    Simple but it works, styling is omitted when you log out and kicks in when you log back in again....

  12. Eric J

    February 2, 2016

    won't this conflict with the WordPress admin bar?

    • Abbey Fitzgerald

      February 3, 2016

      The admin bar is still accessible, there's a pretty high z-index on it of 99999. This has fixed positioning as well.

Join the discussion