Creating a "Sticky" Navigation Bar with Headway


PROBLEM: Your navigation is one of the most important parts of your website. It’s how your visitors get from the homepage to other parts of your site! But once they scroll down to read your content, they can’t see the navigation anymore – and darn it, you want them to see it all the time!

SOLUTION: A sticky navigation bar. You see them all the time (not a Headway site), but how to implement? No worries; it’s actually pretty easy!

Step 1: Set up a WordPress & Headway site with a navigation bar.

Yeah that’s as easy as it sounds. If your site is already completed or in progress, you probably have a navigation bar. If you don’t, go ahead and add a navigation block now.

Step 2: Add a little jQuery Magic

This jQuery script is pretty well commented, but here’s the gist of it:

  1. Hi webpage! Are you being displayed on a mobile device? If you are, we won’t make the navigation sticky because dang, a sticky nav on a mobile device takes up too much room. Oh, you aren’t? Fabulous.
  2. Oh, the window is scrolling! That’s my cue. I’m looking for the .block-type-navigation class. You got one? You do? Fabulous! I’d like to add  a class to it, please. Thanks!
  3. Whoops, you scrolled back up the top. Let’s remove that class, huh? Thanks!

Basically once you scroll down, we are sticking the navigation to the top of the page & making it super obvious to the user that Hey! You! Can! Navigate! There’s more to see!

<script src="//"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
 var isMobile = {
 Android: function() {
 return navigator.userAgent.match(/Android/i) ? true : false;
 BlackBerry: function() {
 return navigator.userAgent.match(/BlackBerry/i) ? true : false;
 iOS: function() {
 return navigator.userAgent.match(/iPhone|iPad|iPod/i) ? true : false;
 Windows: function() {
 return navigator.userAgent.match(/IEMobile/i) ? true : false;
 any: function() {
 return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows());
//Calculate the height of <header>
 //Use outerHeight() instead of height() if have padding
 var aboveHeight = $('.top-row').outerHeight();

 //when scroll

 //if scrolled down more than the header’s height but this isn't mobile
 if ($(window).scrollTop() > aboveHeight && !isMobile.any()){

 // if yes, add “fixed” class to the <nav>
 // add padding top to the #content
 // (value is same as the height of the nav)

 } else {

 // when scroll up or less than aboveHeight,
 // remove the “fixed” class, and the padding-top

A Note on Loading jQuery

This code goes straight into the Header Scripts area of Headway -> Options. The first line ensures that jQuery is being loaded. If you are using a child theme & can load the script via the wp_enqueue function, that’s the preference and you can skip that line!

You could also skip the first script line in the code above (and start at the second < script >
tag), and put this line of code in the Footer Scripts area instead to load jQuery more cleanly. This will prevent jQuery from being loaded twice (and could fix any potential errors).

wp_enqueue_script('jquery-ui', '//', false, false, true);

Two Additional Notes!

Multiple Navigation Blocks: As written, it is going to affect *all* of your navigation blocks. SO if you have two of them on a page, it’s going to look for both! If you want only one of the navigation bars to be affected however, that’s no problem. Just add a custom class to your navigation block (open up the Block Options for the navigation block, and add something in the Config -> Custom Classes input). Then you’ll replace .block-type-navigation with .[yourClassGoesHere]. So if you gave your block a class of stickyNav, your jQuery code would read something like: $(‘.stickyNav’).addClass(‘fixed’).css(‘top’,’0′).next() instead of $(‘.block-type-navigation’).addClass(‘fixed’).css(‘top’,’0′).next(). Remember, there are two places this gets changed in the script!

Taller Navigations Blocks: By default this script is set for a navigation block that is around 42px high. If your navigation block is taller/shorter and this isn’t behaving the way you expect it to, change the line that says ” .css(‘padding-top’,’42px’);” — you’ll change 42 for the height of your navigation block.

Step 3: Add a Little Custom CSS Magic

Finally we need just a teeny little bit of CSS to make this look fabulous & for it to stick! In Design Mode, open up the Live CSS Editor and drop in this code:

.fixed {
     position:fixed !important;
      left: 0;
      text-align: center;
.fixed .block-content {
      display: inline-block;
      text-align: left;
      width: 940px; /* This should be the width of your grid!!! */

The only part of this you’ll need to change is the width — that should be equal to the width of your grid.

Step 4: You’re done!

Aside from lording it over your friends that you just created a sticky nav … you’re all set! Post your site in the comments so we can see how great your site looks!

Spread the word!

86 Responses

  1. I sent demo page to my Android device and the page is shown in the same way as on the desktop. Nothing changes. It doesn’t “response” to my mobile.

  2. Hi, 
    Is there a tweak for this that would allow a separate menu to appear upon scrolling down? 
    Such as here:
    and here:

    • @ramonahux You would want to target a different navigation block, one that you hid from view by default using CSS or the Responsive Grid block hiding. See my note about multiple navigation blocks for a tip on how to target a specific navigation block.

        • @caitlinheadway I do not seem to have the Resposive Grid option to hide a block in the config. Would you be able to point me towards some CSS to hide the block by default?

      • @caitlinheadway Hi Caitlin,
        I’ve tried this with responsive grid hiding but it doesn’t work. The navigation bar merely remains hidden. Is there any CSS you could provide to initially hide the second bar until the user scrolls down?

        • @ramonahux sorry I got all these notifications at the same time 😀 
          You need to add an extra line to the CSS for the .fixed class above – 
          .fixed {
          position:fixed !important;    
           left: 0;      
          text-align: center;
          display: block !important;

        • @caitlinheadway Hi Caitlin,
          Sorry about this. But I have turned on Responsive Grid hiding and entered all the code as above but it isn’t working. The second menu stays either completely hidden (when responsive grid hiding is on) and doesn’t appear on scroll or (when responsive grid hiding is off) is constantly present…

  3. YAYYYYYY!!! Thanks so much @caitlinheadway I will be trying this and I am hoping for good results. I like @ramonahux would love to know how to make them separate. So say on my site, I would just have two separate menus? The main menu and then another one that would be the pop-up overlay menu? But I would have to hide it you say via responsive grid hiding? Not sure how to target the right one and also make it appear and such.

  4. Firstly, thank you for the code. Your explanation was very clear… It took a little tweaking around with but I was able to get it to work…
    My question is how hard would it be to “brand” the floating nav-bar with a logo that floats to the left or right of the menu text or maybe social icons? Should this be feasible? Or is this treading into the ‘extraneous coding’ area? Thanks in advance for any pointers! 🙂

  5. I am using Tabsplus in my site and there are conflict issues
    If I put the jquery link in the header, tabsplus does not work, if I put jquery link in the footer the menu does not work on the pages that Tabsplus is not on.
    Any ideas?

  6. Using the above as soon as you start to scroll the menu becomes sticky, I guess because the class .top-row doesn’t actually exist so you should switch from using the class .top-row to using the actual header element that way it only switches to sticky when the actual height of the header element has been scrolled and not before
    var aboveHeight = $(‘.top-row’).outerHeight();
    should be
    var aboveHeight = $(‘header’).outerHeight();

    • richardvav Good point Richard 🙂 I was using a .top-row in my dev environment at some point but failed to explain that part of my code 🙂 

      If your navigation is not at the top of the screen, you’ll want to change the line there based on the element above the navigation, like .block-type-header (.header won’t do anything unless you define a custom class)

  7. (Apologies for the massive post) I was searching around for something like this and came across a few different scripts, and I think I may have found a simpler way of toggling the class and calculating when to switch the class. This way it calculates where the top of the main-nav (custom class) is and switches the class when the window reaches it. It doesn’t affect the navigation wrap either (which was causing my layout to jump around before), instead it leaves the wrap and moves the .block-content.
    I also kept the first part of your script to check for mobile devices and added it in.
    My only problem is that the submenu drop down animation seems to have stopped working – so, I’m not sure if I’m loading jQuery properly? I tried taking out the first line and adding that other script to the footer like you suggest, but it seems to stop this script from working?
    This is the first time I’ve played around with jQuery properly, so I’m not 100% sure if this is better or not? Here’s the script I’m using (and a demo in jsFiddle:

    <script src=”//”></script>
    <script type=”text/javascript”>
    //when window scrolls
    $(document).scroll(function() {
        // CALCULATE distance of main-nav from top of viewable window
        var menuTop = $(“.main-nav”).offset().top; – $(window).scrollTop();
        //if scrolled down more than main-nav & not mobile then toggle class
        var useStickyNav = $(document).scrollTop() > menuTop  && !isMobile.any();
        $(‘.main-nav .block-content’).toggleClass(‘sticky-nav’, useStickyNav);


  8. Hey, great tutorial, and well needed. I have three menus on this page  but only want to target the last 2. What would I need to do?

  9. Thanks for your post. I have a couple of questions. I viewed your demo
    on two different browsers (FireFox 19 and Safari 5) and it looks pretty
    messed up and unprofessional in the way that it jumps when you start to
    scroll. Is this normal? Also, why do I see two copies of your header
    when I scroll…and why is one of them transparent. Here is a screencast
    that shows exactly what I am describing:

  10. Well, I’ve to add z-index: higher-number to make sure that the header isn’t looking messed up like a see through glass. This must be the ‘messed up’ aspect in the comment by Lazlo.

  11. Great post!

    However, I simply can’t get it to work in responsive mode… it´s still there when in responsive mode, and the “responsive menu” is gone… ?

    Any solution to this problem?


    • Hey Nicolas,

      Thanks for commenting!

      Please create a thread in the support forums under the customization category. Be sure to reference this blog post and include the URL to your site and we’ll get this working for you 🙂

  12. Awesome tutorial – thank you!

    Is there a tweak that I need to make to the CSS if I want to group three blocks together under a custom CSS tag for the jquery call, but still have them hold their position relative to each other?

  13. I (think) I’ve done exactly as instructed (1. load first code block, except first line, in the header scripts location, 2. load jQuery in the footer scripts location, 3. add css and adjust size of grid) and it doesn’t do anything. What else should I do?

    • Hey Jason,

      It’s already possible to do this now in Headway without any additional code. You can simply set the Navigation wrapper to Position: Fixed in the Nudging panel in the Design Editor and then add the necessary margins to the other elements (since the navigation is fixed it won’t push any elements down) and you’ll be set.

      This is something we’ve been looking into to see if we can make it any easier.

      Thanks for the feedback!

      • Hi Clay,

        I’ve tried your method and it works fine.

        Is there a way to hide the fixed bar when on a mobile device so it doesn’t take all the place ?

        Thank You

  14. This is a great method to add Sticky nav to Headway
    Worked perfectly first time, just remember if your logged in the wordpress menu will hide the sticky menu. So check the results in another browser that’s not logged in.

    .fixed {
    .fixed2 {
    padding-top:32px; /*change value to suit your layout*/

    Script (put in footer)

    jQuery(document).ready(function() {
    var row1Height = jQuery(‘header’).outerHeight();
    jQuery(window).scroll(function() {
    if (jQuery(window).scrollTop() > row1Height) {
    jQuery(‘nav’).css(‘max-width’, jQuery(‘nav’).outerWidth() + ‘px’);
    } else {

  15. This was really good,
    I followed the steps and succeeded to make my main menu sticky after scrolling.
    but it works only at homepage. In other pages it breaks and disappears behind some other divisions, however I assigned the highest z-index value, float:none; overflow:hidden; clear:both; to it in css, but didn’t work. I think there’s some conflict.
    Any help would be appreciated.

  16. Hello dear,
    It was really great!
    I’m new to jQuery, it works fine in Chrome and IE but not in Firefox.
    When I add the first script, the one which loads the jQuery, it works in Firefox too but crushes other elements like my slider (I have one slider it stops it).
    However I’ve added the PHP code you mentioned in the footer, but not fixed.
    Any direction would be appreciated.

    • I did my best to modify this for wrappers too. I like bar all the way across)
      In other words like this: (if you don’t find this page you can go to

      THis is the script from tweaked
      (it isn’t perfect because of width of Navigation when screen is reduced), working on it.

      jQuery(document).ready(function() {
      var row1Height = jQuery(‘header’).outerHeight();
      jQuery(window).scroll(function() {
      if (jQuery(window).scrollTop() > row1Height) {
      jQuery(‘nav’).css(‘max-width’, jQuery(‘nav’).outerWidth() + ‘px’);
      } else {

      body.custom .fixed {
      body.custom #wrapper-5.fixed2 {

    • I think I’ve perfected it Use script from above with this CSS
      (Note I’ve tried about 6 ways to do a sticky wrapper and none consistenly work until this one).
      body.custom .fixed {
      body.custom #wrapper-5.fixed2 {
      box-shadow:0 1px 4px #000;

  17. Sticky Navigation works GREAT!
    The drop down submenu feature only works when I’m at the top of the page. As I scroll down, the submenu won’t show. Can someone please help me?

  18. Great article and good explanation.

    It is worth clarifying that if you have the menu on a wrapper, then you should work on the wrapper block and not on the navigation block.

    • There is no wrapper block but a navigation block will always be in a wrapper. It’s up the designer/developer if they want the entire wrapper to stick or just the block.

  19. Thanks for the usefull tip.. Is there also a way for it to also work on mobile phones? I am a beginner in CSS. I used the responsive menu that goes dropdown mode in mobile phones and I want the dropdown menu to also be sticky in the phone when scrolling down. If there is an easy way to do that please let me know.

    Peace and love

    • We’re planning on integrating sticky navigation bars into the core of Headway and it will be responsive.

      Sorry for not having an immediate solution!

  20. First step (putting the code into the header scripts) kills my image slider (meteor). Is there an updated tutorial for this?

    • Not yet but it’s possible the updated tutorial may conflict with other scripts/plugins.

  21. I’ve added a sticky nav bar but when scrolling my blocks > content > body text >
    goes on top of the sticky nav. See
    I’ve tried changing the behaviour to ‘stay in the same position as you scroll (fixed)’ but that doesn’t do anything.
    i just copied and pasted the long code above for the sticky nav and also the code for the design mode and changed the width.

    • Hi Jake,

      I don’t see the javascript or the CSS on your site. If you still want help with this, please post a thread in the forums so we can assist you!

    • The code only applies to the navigation. You’d have to modify it to work with the header block as well.

      A better way to do it: If you have your header block and navigation all in the same wrapper, you could modify the code to apply to the wrapper instead.

  22. Hello,

    I am newbie step 3 and 4 i know where i can find it. But where must insert step 2? Many thanks.

    Best regards,

  23. Hi.
    I am trying to get this to work in Headway, but as soon as I start scrolling the menu just disappears, and the header above it and the rest of the page keep scrolling. Also, the border at the bottom of the navigation wrapper also stays visible and scrolls.
    Does anyone have any suggestions?


    • I would need to see your site in order to see what is happening. You can create a thread in the forum so we can take a look 🙂

  24. Hi,

    Thanks for this helpful post. I do still need help with one particular aspect of the “sticky navbar” part. See here:

    ….when scrolling, the navbar “disappears” behind certain blocks, 3 specifically, the Home Slider bock, the text “promo” block immediately beneath the slider block, and towards the bottom, a graphic block. How do I make it so the navbar stays visible the entire time? Also, if I wanted to apply a solid black stroke/line underneath the navbar, how would I accomplish that?

    Thanks in advance for your help!


    • Hi Gary,

      If you can hang on, this tutorial will not usually be necessary once we release the next version of Headway.

          • Excellent. I hope the sticky menu is responsive and pushes the wrappers beneath the taller header wrapper when scrolled to the top of the page. I’ll wait to implement sticky menus until the new update appears.

  25. Any ETA on this yet? Im using the mystickymenu plugin which works well but would prefer a solution built into Headway.

  26. I’m having problems with the text from my content block appearing on top of my sticky header. Is there an explanation about how to fix this some where?

    • Hi Bruce,
      Please submit a ticket with a link to where we can see this occurring. 🙂 You submit a ticket in your members dashboard under the Support Tab.

Leave a Reply to Andrew Hansen Cancel reply

Copyright © 2016 Vesped Inc. All Rights Reserved. Proudly Powered by Headway and WordPress