28

The perfect responsive menu

 4 years ago
source link: https://www.tuicool.com/articles/NNnue2N
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

On a desktop, websites have the space to show the full menu, but on a mobile device that space isn't there, and you want to hide the menu behind a toggle (like a hamburger icon) and show it when people click that toggle. How do you offer both in an accessible way that keeps your HTML simple, without duplicating your menu? That's what the perfect responsive menu does.

Though the hamburger icon is well known by now, to better help people that are not familiar with it you can show the icon alongside the word "Menu".

In this article, we'll show you how to create a responsive menu that uses the same HTML on all viewports, is responsive and looks great. The perfect responsive menu.

The HTML

We start with the HTML.

<nav id="navigation">
    <button aria-expanded="false" aria-controls="menu">Menu</button>
    <ul id="menu" hidden>
        <li><a href="/">Home</a></li>
        <li><a href="/benefits">Benefits</a></li>
        <li><a href="/pricing">Pricing</a></li>
        <li><a href="/blog">Blog</a></li>
    </ul>
</nav>

The basic menu is as you've probably written before. It's a list of links (an ul ) wrapped in a nav element. But two things are different.

First, there's an extra button. The button has some attributes you might not be familiar with: Aria attributes. With these attributes we can help assistive tools like screen readers know the purpose of the button. In this case, the button controls the element with id "menu", and it's currently not expanded.

Second, The menu is initially hidden, using the hidden attribute. We hide it initially because we developmobile first, and on mobile we only show the button.

The JavaScript

The button by itself won't do anything. For that, we use JavaScript.

const toggleMenu = document.querySelector("#navigation button");
const menu = document.querySelector("#navigation ul");

toggleMenu.addEventListener("click", function () {
  const open = JSON.parse(toggleMenu.getAttribute("aria-expanded"));
  toggleMenu.setAttribute("aria-expanded", !open);
  menu.hidden = !menu.hidden;
});

When you click on the button, we call a function that will get the current value of the "aria-expanded" attribute, and invert it. It will do the same for the "hidden" attribute on the menu. The JSON.parse function helps us convert the attribute from a string to a real boolean.

At this point, the toggle is functional:

See the Pen wvwQwgo by Kilian Valkhof ( @Kilian ) on CodePen .

The CSS

Support for the hidden attribute goes back to IE11, but if you need to support older browsers, then adding the CSS below will let you support them. (keep in mind you might need to change the javascript above too)

[hidden] { display: none; }

At a certain width, the viewport will be wide enough to hide the button and show the menu:

@media ( min-width: 40rem ) {
  #navigation button { display: none }
  #menu { display: block }
}

The width at which this happens depends on your design and the length of your menu, so while 40rem works for me, it might not work for you.

To show this in action, toggle the "CSS" panel in the pen below, it will switch between showing just the button and just the menu.

See the Pen The perfect responsive menu (responsive) by Kilian Valkhof ( @Kilian ) on CodePen .

The finishing touch: styling

At this point, it's up to you how you want to style the button and the menu. You can make it as simple or complicated as you want.

For example, the mobile menu on the Polypane website uses an svg icon for the menu with an animated growing background and a staggered animation of the menu items. I switched to PostCSS (which allows nesting) to make things a little more readable, but it's quite a lot of code regardless.

See the Pen The perfect responsive menu (styled) by Kilian Valkhof ( @Kilian ) on CodePen .

But it doesn't have to look like this. With just this skeleton HTML and JavaScript, you can use CSS to style it in many different ways. You might choose to slide open the menu like a dropdown, pushing the rest of the content down, or you could have it slide in from the left like a side panel. And using css transforms you can animate the transition in any way you like.

As long as you keep the HTML and the core functionality of the JavaScript intact, you will have an accessible, responsive menu that uses the same HTML on both mobile and wider viewports. The perfect responsive menu.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK