A sticky menu is a menu that appears usually on the top of the window after your primary menu scrolls out of view.
The wp-responsive-menu plugin creates a fixed menu (but as a burger menu icon) on the top if the screen size is indicative of a mobile device. Here, though, we want a full menu showing for desktop/laptop viewing. There are multiple ways one could do this.
- Using css have your main menu always fixed to the top.
- One could add JavaScript that listens whenever the window is scrolled, to change the main menu container to a fixed position when the top of the main menu container reaches the top of the window.
- One could create a second menu with display none and add JavaScript to listen whenever the window is scrolled, to show this fixed menu after the window has scrolled a certain amount. This post shows how to do this if you are using the Genesis framework: http://my.studiopress.com/tutorials/sticky-menu/
- Could we add some PHP to create a copy of the main menu markup but with the primary class changed? Instead of having to maintain two main menus, this copy would be the sticky menu. We’ll need to add some JavaScript listening on the scroll event.
In this post we are going to go with the 4th option . First, getting a copy of the main menu markup is pretty easy. In the theme functions.php add the following:
add_action('genesis_after_footer','agct_sticky_menu');
function agct_sticky_menu(){
wp_nav_menu( array(
'container' => 'div',
'container_class' => 'agct_sticky nav-primary',
'menu_class' => 'genesis-nav-menu',
'theme_location' => 'primary'
) );
}
We kept the menu_class of ‘genesis-nav-menu’ and kept the container class of ‘nav-primary.’ We want this so that it will be styled the same as the main menu. We changed the container from ‘nav’ to ‘div’ (assuming you are using html5) and added the class ‘agct_sticky.’ We’ll use this class to add the necessary styles to this menu copy and to target this copy in our JavaScript.
Next, we’ll want to add the css to put this menu at the top of the page in a fixed position. We also want it to initially be hidden.
.agct_sticky {
display: none;
position: fixed;
top: 0;
left:0;
right:0;
}
In the above css we could change the background color and/or make it semi-transparent, etc.
Finally, we need the JavaScript to monitor the scroll event and determine when to show our sticky menu.
jQuery(function($){
var $mainMenu = $('nav.nav-primary'),
$stickyMenu = $('.agct_sticky');
$(window).on('scroll', function() {
var windowTop = $(this).scrollTop(); //get top of window
var mainMenuBottom = $mainMenu.offset().top + $mainMenu.height(); //bottom of main menu
if( windowTop >= mainMenuBottom ) { //main Menu is no longer showing
$stickyMenu.slideDown(); //show our sticky menu
} else {
$stickyMenu.slideUp(); //hide our sticky menu
}
});
});
To have the JavaScript loaded on the page, you’ll need to add another snippet of code to your functions.php (this is assuming you saved the JavaScript in a file called ‘sticky.js’ in a directory called ‘js’ under your theme directory) :
add_action( 'wp_enqueue_scripts', 'agct_sticky_load_scripts' );
function agct_sticky_load_scripts(){
wp_enqueue_script('sticky_menu', get_stylesheet_directory_uri() . '/js/sticky.js', array( 'jquery' ),'1.0.0',true);
}
No extra code needed. This was fun to create.