Create Better Divi Headers

Show/Hide Divi Header Depending on Page Scroll Direction

by | Jun 18, 2019 | 20 comments

In this tutorial I’ll show how to show/hide Divi header bar depending on page scroll direction. The header will hide while the page is being scrolled down, and will show up only when the page starts scrolling up.

Table of Contents

Demo

Why Show/Hide The Header On Scroll?

Inline headers move out of the viewport when the page is scrolled down and in order to navigate to other pages users have to scroll all the way up to click the other menu links.

This is not the best user experience and one of the solutions to improve it is to make the header fixed so that it always stays in the viewport while the page is being scrolled.

This allows the users to navigate through website without having to scroll the page all the way up every time they need to use the navigation.

However, a fixed header comes with its own disadvantage too – it covers a portion of the page content which can be a considerable issue for small mobile devices screens, especially if the header bar is thick (like the Divi theme Centered header style on mobile).

So, to prevent this there is a need for a “hybrid” header which would be fixed but move out of the viewport while the page is being scrolled down and appear only when the visitor starts scrolling the page up.

And this is what we are going to implement now.

Implementation

To implement this functionality we will use a little bit of CSS to make the header fixed on mobile devices, and also make it show/hide smoothly when the page is being scrolled up and down.

The scroll direction detection and showing/hiding the header will be implemented using jQuery.

So, let’s do that in a few simple steps as explained below.

Step 1. Enable Divi Fixed Navigation

We need the header to be fixed, so, enable the Fixed Navigation Bar option in Divi Theme Options.

However, this will make fixed only the desktop menu but we need to make divi mobile menu fixed as well.

And we can do that using the following simple CSS:

@media all and (max-width: 980px){
  /* make mobile header fixed */
  #main-header,
  #top-header {
    position: fixed;
  }
}

Step 2. Show/Hide The Header Smoothly

The header should move in and out of the viewport on scroll smoothly, so, we need to apply transitions accordingly. Here is the CSS:

/* show/hide the main and top header smoothly */
#main-header,
#top-header {
  transition: top .3s ease;
}

Step 3. Add The Effect Custom CSS

Combine both CSS snippets provided above and add it into Divi Theme Options -> General -> Custom CSS field.

Alternatively, if you are using a child theme then you can add the CSS into the child theme’s style.css file.

/* Show / Hide Divi Header Depending On Page Scroll Direction */

@media all and (max-width: 980px){
  /* make mobile header fixed */
  #main-header,
  #top-header {
    position: fixed;
  }
}
/* show/hide the main and top header smoothly */
#main-header,
#top-header {
  transition: top .3s ease;
}

/* Show / Hide Divi Header Depending On Page Scroll Direction */

Step 4. Add The Effect Custom JS

Next step is to add the effect’s JS code in Divi Theme Options -> Integration field. Make sure it’s enclosed in script tags.

<script type="text/javascript">
(function($){
    $(window).load(function(){
        let minScroll = 5,
            interval = 0,
            closeDropdownOnScroll = true,
            didScroll,
            lastScrollTop = $(document).scrollTop(),
            topHeader = $('#top-header'),
            mainHeaderHeight = $('#main-header').outerHeight(),
            topHeaderHeight = topHeader.length ? $('#top-header').outerHeight() : 0,
            mainHeaderTopOffset = mainHeaderHeight + topHeaderHeight;

        $(window).scroll(function(e){
            didScroll = true;
            if(closeDropdownOnScroll){
                closeDropdownMenu();
            }
        });
            
        setInterval(function(){
            if (didScroll){
                hasScrolled();
                didScroll = false;
            }
        }, interval);
        
        /**
         * Close dropdown menu
         */ 
        function closeDropdownMenu(){
            $("#main-header .mobile_nav.opened .mobile_menu_bar_toggle").trigger("click");
        }

        /**
         * Show/hide header
         */      
        function hasScrolled(){
            let scrollTop = $(this).scrollTop();
            
            // Make sure the scrolled amount is more than minScroll
            if(Math.abs(lastScrollTop - scrollTop) <= minScroll)
                return;
            
            // If the page's been scrolled down by more than the header height - hide the header.
            if (scrollTop > lastScrollTop && scrollTop > mainHeaderTopOffset){
                // Hide the main header
                $('#main-header').removeClass('nav-down').addClass('nav-up');
                $('#main-header.nav-up').css({'top' : `-${mainHeaderTopOffset}px`});

                // Hide the top header (if exists)
                if(topHeader.length){
                    $('#top-header').removeClass('nav-down').addClass('nav-up');
                    $('#top-header.nav-up').css({'top' : `-${topHeaderHeight}px`});
                }
                
            } else {
                // Show the header when scrolling up
                if(scrollTop + $(window).height() < $(document).height()){
                    // Show the main header
                    $('#main-header').removeClass('nav-up').addClass('nav-down');
                    $('#main-header.nav-down').css({'top' : `${topHeaderHeight}px`});

                    // Show the top header (if exists)
                    if(topHeader.length){
                        $('#top-header').removeClass('nav-up').addClass('nav-down');
                        $('#top-header.nav-down').css({'top' : `0px`});
                    }
                }
            }
            
            // Update the last scroll position
            lastScrollTop = scrollTop;
        }
    });	  
})(jQuery); 
</script>

This jQuery snippet detects page scrolling direction and shows/hides the header bar accordingly, depending on the configurations applied (read below).

Additionally, if the mobile dropdown menu is open when the page is scrolled up, it will close the dropdown menu so that the user can continue browsing the page content without having to close the dropdown menu manually.

And, finally, if the pages is scrolled down the open mobile dropdown menu will again get closed automatically, and the header bar will move out of the viewport.

Step 5. Configure The Show/Hide Effect Features

By default the effect will trigger as soon as user starts scrolling the page without any delay and scroll amount requirements. And closing the open mobile menu automatically is enabled.

However, you can configure these features to your linking using the following variables: minScroll, interval, closeDropdownOnScroll.

Configure The Show/Hide Divi Header Depending on Page Scroll Direction Effect Features

Set A Minimum Scroll Amount

Use the minScroll varible to set the minimum amount to be scrolled before the effect takes place.

For example, if it is set to 250 then the header will be hidden only after the page has been scrolled down by at least 250px (default: 5)

Delay The Effect

Use the interval variable to delay the effect by specified amount of time (in ms) after the scrolling starts.

By default the effect is triggered immediately when the scrolling starts (default: 0).

Close Mobile Dropdown Menu When Scrolling Starts

Use the closeDropdownOnScroll variable to enable/disable the automatic closing of the open mobile dropdown menu feature.

Set it to true if you want the menu to close automatically, otherwise set it to false (default: true).

Conclusion

By following these steps you can enhance your Divi website’s navigation experience (especially on mobile devices) by creating a header that adapts dynamically to user behavior.

This show/hide effect not only improves site usability by maximizing screen space but also maintains easy access to the site navigation when needed.

Try implementing this feature to make your site more user-friendly and responsive to visitor interactions. Also, feel free to experiment with the settings to suit your specific design needs.

And don’t hesitate to share your thoughts and ask questions(if any) in the comments section below.

View Live Demos & Get Divi MadMenu

    Download FREE Divi Sections

      20 Comments

      1. Beni

        Works all fine. Thank You. One question: How can i manage that the menu is showing in the beginning when the page is loaded and disappears when first time scrolling?

        Reply
      2. Helen

        Hi there.

        What a great header! I have an issue though. My DIVI header is made up of a section containing rows and it only seems to apply the effect to the top row rather than to both. Is there any way round this?

        Reply
      3. Patricia Martos

        I made my header on the Divi Theme Builder and it seems the code is not working in this case.

        Any tip?

        Thanks!!

        Reply
      4. Sue

        This looks great, but I’ve got a problem. Everything works until I scroll back to the top of the page. When I return to the top, the Primary Menu Bar, on desktop I can only see the bottom half of my logo, and a bit of the top of my main menu is cut off. On mobile, more than 95% of the logo is cut off (I can see a little bit of the bottom of it), and the hamburger menu is not visible. Can I force a certain height when I get all the way back to the top of the Primary Menu Bar?

        Reply
        • Ivan Chi

          Hi Sue.

          Most probably the header is being applied some negative top offset or negative margin-top for some reason, please use the browser dev tools to inspect the header and find out what is making it move out of the viewport.

          Reply
      5. Jimmy

        Thanks a lot for sharing this, it worked for me perfectly.

        Reply
      6. Maurice

        Works great – btw the addon you mentioned above to disable it on desktop (mobile only) works like a charm:

        /* disable the effect on desktop */
        @media all and (min-width: 981px){
        #main-header {
        top: 31px !important;
        }
        #top-header {
        top: 0 !important;
        }
        }

        Reply
      7. Phil

        Howdy Ivan.

        Can you also implement this on the Global Header??

        Cheers.

        Reply
      8. Shakeel Anjum

        Wow, it’s working perfectly on my blog how2wp.com

        Thank you so much, Ivan, for creating such an awesome tutorial.

        Reply
      9. Rajib Mridha

        Just Wow. I was looking for it a long time ago. By the way, thank you for your great tutorial and thanks again to suggest me to visit this group.

        Reply
      10. David

        I got it working on mobile but after I added the JS the desktop fix nav doesn’t work anymore.

        Reply
        • Ivan Chi

          Check the console if there are any errors.

          Reply
          • David

            No errors in console. I noticed the desktop is trying to do the same as the mobile is suppose to.

            Reply
            • Ivan Chi

              Yes, it works for desktop header too, not just for the mobile header, it is supposed to be so.

              If you don’t want the desktop header to be affected then try setting the header top offset to 0(zero) so that it overrides the top offset value set by JS (you’ll probably have to use !important for that) inside the desktop @media query.

              If you have the Secondary header enabled then set the secondary header top offset to 0(zero) but the Primary header top offset should be the same as the height of the Secondary header.

              Reply
              • David

                I can’t seem to work out where to make those changes. I couldn’t see offset in css and I did find offset in js but there was no value there. How do I –

                set the header top offset to 0(zero) so that it overrides the top offset value set by JS (you’ll probably have to use !important for that) inside the desktop @media query.

              • Ivan Chi

                Try this:

                /* disable the effect on desktop */
                @media all and (min-width: 981px){
                #main-header {
                top: 31px !important;
                }
                #top-header {
                top: 0 !important;
                }
                }

      11. Samar

        Awesome tutorial.

        Reply
        • Ivan Chi

          Thanks :)

          Reply
      12. Asit Aithal

        Great tip. The only issue is that if I have my secondary menu turned on, it disappears after the initial scroll.

        Reply
        • Ivan Chi

          Does it happen to the secondary menu only or both? Tested again with the secondary menu enabled and seems to work just fine, no issues.

          Reply

      Submit a Comment

      Your email address will not be published. Required fields are marked *

      Get FREE Divi Layouts

      Download 20+ Divi templates for FREE!

      Please confirm your email address to complete your subscription. Thank you!

      Copy link