Hey quick! You’ve gotta create the navigation for the site and you start working on the mobile behavior. What pattern do you choose? If you’re like most folks, it’s probably the “hamburger” menu that, when clicked, uses a little JavaScript to expand a vertical list of navigation links.
But that’s not the only option.
Depending on the context and contents of the navigation, there may be a JavaScript-free method that gets the job done while providing a more accessible experience.
It is considered best practice to use a progressive enhancement approach, building webpages for users with the oldest and least capable technology first, then introducing additional enhancements as support allows. If you can provide a quality experience for users with basic technology, then you might consider whether or not your webpage even requires JavaScript functionality at all. Leaving JavaScript out of the navigation can ensure that users are able to navigate your website even if JavaScript is disabled or network issues prevent scripts from loading — which are definitely wins.
Let’s look at three alternative patterns to the JavaScript-powered hamburger menu.
Alternative 1: Put the menu on a separate page
Who said navigation has to be in the header of every page? If your front end is extremely lightweight or if you have a long list of menu items to display in your navigation, the most practical method might be to create a separate page to list them all. The lightweight WordPress theme Susty utilizes this method for its navigation.
This pattern is especially useful for static websites that use filesystem routing. If the project is built using a static site generator, the page load might be imperceptible to the user and have the added benefit of keeping your templates as modular as possible.
All this takes is basically replacing the “Menu” button with a close button instead when the user is on the menu page. When clicked, we can take the user back to the last page they were on in a couple of ways. If we are using a server-side CMS, like WordPress, then we can grab the last URL using $_SERVER['HTTP_REFERER']
and set it as the “close” button URL.
But if we’re not using a server-side setup then, yeah, we might need a few lines of JavaScript to get that last URL.
<a href="https://MyHomePage.com" onclick="handleClick(event)">×</a>
<script>
function handleClick(event) {
// Don't follow the link
event.preventDefault();
// Go back to last visited page
window.history.back();
// Bail out of the function
return false;
}
</script>
So, while I like this method and pattern, it might require JavaScript depending on the project.
Alternative 2: The horizontal scroller
This approach is perfect for shorter link lists and allows users to access all of the navigation items without opening anything or clicking away from where they are. GitHub uses this approach for sub-menus.
Using flexbox combined with a scrolling overflow in CSS will do the trick!
Alternative 3: The CSS-only hamburger menu
Just because the hamburger menu pattern is often done with JavaScript doesn’t mean we have to use JavaScript. Using CSS pseudo-selectors and an HTML <input>
, we can create a rich mobile menu and save JavaScript for other functionality that actually requires it.
See? Just because a convention is popular doesn’t mean it is the only way to do things. There are often simpler, more accessible methods, especially when it comes to navigation. It’s not much work to create functional, lightweight, immersive navigation without JavaScript and we get some nice benefits along the way. If you’ve created any interesting CSS-only navigation patterns, I’d love to see them — please share in the comments!
I often use hash anchor links and the :target psuedo state for noscript friendly functionality. Might be worth updating this post with some additional tactics! :)
Can you elaborate? That sounds clever :)
Very nice
there is an example at w3schools https://www.w3schools.com/cssref/sel_target.asp
Why not use an Ambidextrous, Thumb Zone Friendly, Mobile Navigation Menu?
It uses a HTML5 and CSS3 ONLY “Full Screen Overlay Scrolling Menu”.
Is positioned at the bottom of the Smartphone screen.
It is both Transparent and Opaque to alert the user to Scroll Down to continue viewing additional Content, Menu Categories or Web Page Links that can not be displayed on the screen.
All Menu Categories and Links are “Centered” and optimized for “ONE HANDED” use with either the Left Hand or Right Hand.
Visit https://www.raulgonzalez.com/thumbzone.html
Love the first two! My only concern is screen reader accessibility for the 3rd alternative. The checkbox “hack” creates confusion for those users unless its semantics are properly overridden with aria attributes (even then I’m not sure it’s entirely possible or has wide-ranging support across screen readers). Demographics do come into play, so if you don’t care about screen readers, it’s a non-issue, otherwise JavaScript is the better option in that case.
Boom! Was thinking same about the third one and accessibility.
I’ve used the “abuse a checkbox” approach for “hamburger” menus for ages, and wrote my own article about it.
https://cutcodedown.com/tutorial/mobileMenu
Similarly related is the use of :target to handle modals — like a login form modal — without scripting:
https://cutcodedown.com/tutorial/modalDialogs
It’s something I’ve been trying for a decade to drive home with beginners and alleged “experts” alike, is stop using JavaScript for things HTML and CSS can do just fine all by their lonesome! More so when it’s actually easier to just use CSS, and maybe the occasional scripting to enhance the already working code.
For example I have my own little x86 ASM reference I cobbled together from different sources, where the entire reference is a single HTML file, but behaves like multi-page site. It has modal dialogs for the reference, filtering of processor level operations, and a host of other things… and 98%+ of the functionality is provided by CSS.
https://x86.cutcodedown.com/
The whole thing is three files (not counting the advert)… and seriously get a load out of how little JavaScript the page uses:
https://x86.cutcodedown.com/intel.js
Apart from telling IE users to suck it, all the scripting does is detect if there’s a H2 inside a hash target and assign it to the title, and make sure any INPUT/checkbox driven modals are closed.
Though I weep every time I see pointless DIV being wasted to make a hamburger icon when we have perfectly good generated content. Border the label, label:before and :after set a fixed height (gap between lines), use border to make the liens top and bottom, then remove the top border from the bottom one.
How about browsers that don’t support css? How about showing menu to people who surf using wget?
Jokes apart, after microsoft started pushing edge forcefully to win 7 users; compatibility issues should now be solved!!
IMHO, those who don’t have js enabled should be kicked out of the site. These are mostly bots, and they are good for nothing; except increasing your bandwidth.
My two cents.
100% agreed. Option 3 is not accessible.
To use this method, you’ll still want to apply JS to the input so that it can be checked with the press of an <Enter>.
And give it some :focus styling, so that a keyboard user can see when they’ve tabbed to it.
In any case, I love articles like this, fun stuff.
There’s an incorrect comment in the final CSS about transforming the hamburger into an X. That would be a lovely animation to see if you can pull it off!
Another option could be to simply display a basic navigation pattern without the hamburger menu – i.e. make the list items inline-block or block (when multi-level).
This is what Astra does if the JavaScript file fails to load, or if the site is viewed on older and less capable browsers. Astro is a mobile-first navigation pattern, with an optional expand-and-collapse menu on small screens.
http://cferdinandi.github.io/astro/
Astro is one among many lightweight Vanilla JavaScript plugins bt Chris Fredinandi https://vanillajstoolkit.com/plugins/
Still, I’d like to use javascript as it gives us an ability to do it in our own way, and I don’t see any disadvantage of using JS.
Another option is to use the default behaviour of the HTML
<details≥
and<summary>
tags. This is not semantically correct per se, but this wouldn’t be the first time we is it ? ;) With some CSS transition we can obtain a pretty functionnal menu.I wonder if the
<summary>
and<details>
elements could be used for expanding navigation (without pushing page contents downwards).I use option 2 – horizontal scrollbar – which I progressively enhance with JS to add a hamburger button that toggles the visibility of the menu on mobile.
On desktop, the same HTML is used, and the menu is transformed by CSS into a mega-nav. A little bit of JS enhancement is added too.
But essentially, with no-JS, the menu is just a bunch of nested
<ul>
. Totally usable, albeit maybe not that pretty.I’ve done a css only navbar with the use of a checkbox and the :checked selector
https://shaba-seo.netlify.app/index.html
I’m a bit curious about Alternative 1 and how would search engines see it?
I’ve done a css only navbar with the use of a checkbox and the :checked pseudo selector. I made use of pure css to style the side bar menu. What do you think about this alternative…..do drop your comments
https://shaba-seo.netlify.app/index.html
I once had to create a nav menu without JS, so I developed HyperNav. Check it out if interested.
GitHub: https://github.com/Acmion/HyperNav
So useful!
Might I suggest adding:
This should prevent undesired backward/forward navigation when hitting the ends of the menu.
We’ve been using the
<details>
element for menus. It’s actually a nice lightweight solution for all kinds of show/hide situations.Alternative 1 is a nice option that I haven’t seen before. To avoid using JavaScript the X could be removed altogether. There is a browser back button after all, and the intention of opening a menu is to visit another page.
Oh damn!
That’s why they call in here the ‘CSS-tricks’.
3rd one hella amazing.