How to create a menu with Divi that show and hide as you scroll in 4 steps.

Jérémie Litzler
4 min readSep 22, 2020
Final result!

Out of the box, the Divi options for the header are poor. The fixed, always showing header is not nice and it can mess up your layout.

I searched and found propositions to hide or show the header on scroll movement, even from Elegant themes themselves, none worked.

So I dug into it and found a solution, with help.

1. Create the global header

Default site page

In your theme builder, add a custom header then select “Build From Scratch”

2. Build your header first

Usually a header is made of:

  • an icon,
  • a list of links.
Example of menu

3. Adjust the settings of the section

First, in the section module, in the advanced settings, set the ID of the header. Ex: global-header.

You will need to use this in the JavaScript and CSS code later on.

Set the ID of the header on the section module

Then adjust the width to 100%:

100% or 100vw, as you see fit

4. Add a code module to enable the scroll effect

You can add the code module under the menu, like so:

Module-only view

PS: to edit the code module afterwards, use the module-only view:

How to access Module-only view

With the following JavaScript, you will be able to detect when you scroll up or down.

It is the only solution I have found to work without having the shaking effect on the screen.

It works fine both in Chrome, Firefox, Edge and IE 11.

<script>
/*!
* Run a callback after the user scrolls, calculating the distance and direction scrolled
* (c) 2019 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Function} callback The callback function to run
* @param {Integer} refresh How long to wait between scroll events [optional]
*/
var scrollDistance = function (callback, refresh) {
// Make sure a valid callback was provided
if (!callback || typeof callback !== 'function') return;
// Variables
var isScrolling, start, end, distance;
// Listen for scroll events
window.addEventListener('scroll', function (event) {
// Set starting position
if (!start) {
start = window.pageYOffset;
}
// Clear our timeout throughout the scroll
window.clearTimeout(isScrolling);
// Set a timeout to run after scrolling ends
isScrolling = setTimeout(function() {
// Calculate distance
end = window.pageYOffset;
distance = end - start;
console.log("distance:" + distance);
// Run the callback
callback(distance, start, end);
// Reset calculations
start = null;
end = null;
distance = null;
}, refresh || 66);}, false);};

var globalHeader = document.getElementById("global-header");
scrollDistance(function (distance) {
//console.log('You travelled ' + parseInt(Math.abs(distance), 10) + 'px ' + (distance < 0 ? 'up' : 'down'));
if (distance > 0) {
globalHeader.classList.remove("show-header");
globalHeader.classList.add("hide-header");
return;
}
globalHeader.classList.remove("hide-header");
globalHeader.classList.add("show-header");
});
</script>

And the CSS to control the hide and show CSS class:

<style>
#main-content{
margin-top: 5em;
}

.hide-header {
opacity: 0;
margin-top: -5em !important;
}

.show-header {
opacity: 1;
margin-top: 0px !important;
}

#global-header {
position: fixed!important;
top:0;
-webkit-transition: all 250ms ease !important;
-moz-transition: all 250ms ease !important;
-o-transition: all 250ms ease !important;
-ms-transition: all 250ms ease !important;
transition: all 250ms ease !important;
}
</style>

Of course, you can adjust the CSS to your need.

I hope that was helpful. If so, share it :-)

Big thanks to @Chris Ferdinandi.

--

--

Jérémie Litzler

I am a software engineer, but not just that: I thrive to improve life around me through observation and awareness about my impact in my environment.