Navigation is one of the most challenging battles for doing responsive design well. To preface this article, I highly recommend you study Brad Frost’s collections of responsive navigation patterns and complex responsive navigation patterns. In this post, I’ll cover two methods for handling the “toggle” method for responsive navigation in WordPress.
Common responsive navigation patterns in WordPress
There are many possible approaches to responsive navigation. But other than the “do nothing” approach, the “toggle” method for handling responsive navigation is by far the most popular I’ve seen in WordPress themes.
The toggle method is typically represented by a button with text or a “hamburger” icon replacing an inline navigation method once the screen size shrinks to a particular size. The trigger for the toggle method is where I’d like to focus.
Toggle Method 1 — jQuery resize and window width
I’ve used a method very similar to this ever since I studied it in the _s theme over a year ago. Essentially, the trigger is handled by identifying the window width at any time with $( window ).width()
. I’ll have a full view of a slightly updated version of this code below, but you can see this method in this gist as well.
When the window width is above 600px, the main-navigation
class is utilized, and when the window is below 600px, main-small-navigation
is utilized for the menu itself. Also, the h1
used for assistive text (for accessibility purposes) is altered to be the menu toggle and associated text, triggered by jQuery’s .click
function.
Therefore, the menu is able to be turned into a click-activated toggled navigation method for small views.
This is a pretty good solution, and has been used quite a bit. One pet peeve of mine for this solution is the hard coded pixel value for where the menu breaks. It’s fine for if you build parent themes from starters such as _s, but distributed parent themes that anticipate child theme usage and customization should do better. We could make the hard-coded valuable filterable by PHP using wp_localize_script
.
Integrate wp_localize_script for flexibility
Here’s an example alternative JavaScript file and corresponding enqueue that utilizes wp_localize_script
, making the hardcoded valuable filterable with PHP.
[gist id=”6386511″ file=”small-menu.js”]
You can see the small_menu_vars.size
variable in place of the previously hardcoded number value. This variable is able to utilize dynamic data thanks to WordPress’ wonderful wp_localize_script
function, so well taught by Pippin Williamson last year. I think this particular use case can be quite useful, especially with distributed parent themes.
In order for us to be able to utilize this variable, we need to properly set up our variable with wp_localize_script
. Here’s the corresponding code that will look familiar after reading Pippin’s tutorial.
[gist id=”6386511″ file=”sample-functions-enqueue.php”]
Did you notice the filter? That’s where the fun is. We can now make this number, previously hard coded, filterable from child themes. Here’s a sample filter.
[gist id=”6386511″ file=”sample-functions-child-theme.php”]
Now your child themes can easily change the break point for the responsive navigation without dequeueing the file and enqueueing a new one.
Toggle Method 2 — JavaScript and CSS media query
The previous script does rely on jQuery, and if your project doesn’t need jQuery otherwise (granted, this is unlikely these days) you may look for an alternative solution. Or you just might like the idea of handling the breakpoint in a little cleaner way with a CSS media query.
The _s theme’s latest navigation iteration uses a jQuery-less JavaScript implementation to help identify the current state of the page’s markup and make a CSS-based toggle menu super simple.
First, take a look at the navigation markup.
[gist id=”6386589″ file=”s-theme-header-markup.php”]
One thing you’ll notice is that the menu-toggle class is on the h1
from the very beginning now. Literally all our Javascript will do is enable the click function for the h1
using the toggled class. The h1
(toggle menu) is hidden by default with display: none;
and altered with a media query for max-width: 600px
to display: block;
. At the same time, our standard menu is hidden by default and only shown when the toggled class is activated.
[gist id=”6386589″ file=”nav-styles.css”]
The meat of the Javascript that does this is at the bottom of the file. The first 15 lines or so are simply checking to make sure that the various parts of the menu exist, and if they don’t, prevents the JavaScript from doing anything.
The button variable is being defined by grabbing the h1
within #site-navigation
(which is the container variable).
[gist id=”6386589″ file=”navigation.js”]
Notice there was no hardcoded value for the width to set a navigation breakpoint for toggling. It’s all in the CSS. Because the decision making is all in the CSS, it makes the transition from toggled to not toggled faster as well.
Flexibility for distributed themes
Since the value for the breakpoints are in CSS with this method, it’s a bit more flexible than our previous method. However, it could be a bit weird to override the media query in a child theme to adjust where the break occurs.
Which method is better?
I think in almost all situations, the second method without jQuery and handled via CSS is better. It’s fast, flexible, and has great support.
However, some distributed themes may be structured in a way that overriding the CSS media query could be difficult and would prefer the flexibility of the jQuery solution and wp_localize_script
.
Some other themes may already use something similar to the first method, and want the flexibility, but need to keep backward compatibility in mind. In that case, it’s trivial to add the support for flexible breakpoints with wp_localize_script
.
If your website doesn’t have a distributed parent theme that already utilizes another method, the new _s method is probably a no-brainer.
Hi Brian,
I like the article, but just wanted to let you know I’m seeing the following error a few times in it:
Could not embed GitHub Gist 6386511: API rate limit exceeded for 108.174.154.155. See http://developer.github.com/v3/#rate-limiting for details.
Congrats, Brian on hitting the GitHub gist API rate limit. Didn’t know there was one, and don’t know what to do when you hit it. 🙂
The API limit is very small for unauthenticated users (60 requests per hour). You need to create a GitHub account, and be logged in to increase the limit to 5000 requests per hour. Or just wait a bit for the limit to reset.
Not sure I like _s non-mobile first approach, but I dig the vanilla JS used.
I’ve started using this jQuery plugin: http://www.meanthemes.com/plugins/meanmenu/
Works very nicely and under a certain pixel width that you specify it replaces your existing nav.
How do you implement the plugin, I’m having trouble with it.
I learned something new from this and would love to see more of these tutorial type posts from you.