How to create a menu with Divi that show and hide as you scroll in 4 steps.
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
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.
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.
Then adjust the width to 100%:
4. Add a code module to enable the scroll effect
You can add the code module under the menu, like so:
PS: to edit the code module afterwards, use the 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.