Hey Phoebe!
This will be a little bit involved, as we need to do several different things:
– register the menu
– call the new menu so it’s displayed
– add Javascript to allow the menu to be toggled on mobile devices
– add Javascript to make the menu stick
– position the menu with CSS
Ready? Let’s dive in! First, make sure you have a child theme ready to do all of this in.
In your child theme’s functions.php
file, we’ll register our new menu:
register_nav_menus( array(
'sticky' => esc_html__( 'Sticky Menu', 'argent' ),
) );
I’ve named the menu Sticky Menu and given it a similar ID.
Next, we’ll need to display that menu. Make a copy of the parent theme’s header.php
file in your child theme folder. In that copy, we’ll add a call to the new menu. It should go between the end of the .site-branding
element and the end of the #masthead
element. In the original file, that puts it on or around line 35. Here’s the code:
<nav id="sricky-navigation" class="main-navigation" role="navigation">
<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false"><?php _e( 'Menu', 'argent' ); ?></button>
<?php wp_nav_menu( array( 'theme_location' => 'sticky', 'menu_id' => 'sticky-menu' ) ); ?>
</nav><!-- #sticky-navigation -->
That will display our new menu – and keep the same CSS classes as the original menu so they look the same.
At this point, if you install the child theme, you can add items to the new menu, and see it below your header – but it won’t open and close when you tap the button on mobile devices, and it won’t stick to the header.
Next, we move on to Javascript. In your child theme folder, create a new folder named js
.
Inside that folder, make a copy of the parent theme’s /js/navigation.js
file.
We’re going to start by renaming this copy to sticky-navigation.js
Now, near the beginning of this file, you’ll see the following line:
container = document.getElementById( 'site-navigation' );
On that line, change site-navigation
to sticky-navigation
. That tells this script to look for our new menu’s HTML ID, instead of the original one. That’ll make the mobile toggle work (once we enqueue this script, a little later on).
Next – we need to add to this Javascript, to create the stick effect (using the Stackoverflow you linked to as a base).
To accomplish that, we’re going to add a function to the end of the file. After the end of the current code, add the following:
// Stick secondary menu to top when scrolling
(function ($) {
$(document).ready(function () {
$(window).scroll(function () {
if ($(window).scrollTop() > $('#masthead').height()) {
$('#sticky-navigation').addClass('navbar-fixed');
}
if ($(window).scrollTop() < $('#masthead').height()) {
$('#sticky-navigation').removeClass('navbar-fixed');
}
});
});
})( jQuery );
Now we have a menu that will stick when it reaches the top of the screen!
Let’s put all of that Javascript to work. In your child theme’s functions.php
file, we’ll enqueue the script, like so:
// Enqueue custom scripts
function my_argent_scripts() {
wp_enqueue_script( 'sticky-navigation', get_stylesheet_directory_uri() . '/js/sticky-navigation.js', array(), '20120206', true );
}
add_action( 'wp_enqueue_scripts', 'my_argent_scripts' );
That activates the Javascript on the page.
Lastly, we need some CSS to position it properly – both for your visitors, and for you when you’re logged in and you can see the admin bar (we don’t want an overlap!).
.navbar-fixed {
top: 0;
z-index: 100;
position: fixed;
width: 100%;
}
@media screen and ( min-width: 600px ) and ( max-width: 784px ){
.admin-bar .navbar-fixed {
top: 46px
}
}
@media screen and ( min-width: 785px ) {
.admin-bar .navbar-fixed {
top: 32px
}
}
I’d also add the caveat that I’m not a Javascript expert – so while the above should work (it’s working now on my test site), it’s possible someone else may have an alternate/better solution ??