Building a Modern Website
Part 5: Navigation That Works for Everyone

Navigation That Works for Everyone
When building navigation it is tempting to focus on how it looks and how smooth the interactions feel. But navigation is one of the most critical parts of any website. If users cannot move through the site easily, the rest of the experience does not matter much.
Accessibility should therefore not be something that is added afterwards. It should be part of the foundation from the beginning.
A good starting point is to remember that not everyone uses a mouse or a touchscreen. Many users rely on a keyboard to move through a page. Others depend on assistive technologies such as screen readers. If the navigation works well with these tools, it will usually work well for everyone.
Keyboard navigation
A simple but powerful rule is that everything interactive must be reachable and usable with a keyboard.
Links, buttons, and menu items should be reachable with the Tab key and activated with Enter or Space. If a navigation element requires a mouse to function, it is very likely that something has been implemented incorrectly.
Native HTML elements help a lot here. A <button> behaves like a button. A <a> behaves like a link. If you replace these with generic <div> elements you suddenly need to rebuild a lot of behaviour that the browser already provides for free.
<nav aria-label="Main navigation">
<ul class="nav-list">
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/series">Series</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
Notice: we are not adding any ARIA roles here. The HTML elements already describe their purpose. This is usually the best possible accessibility solution.
This is one of the reasons why semantic HTML is such a strong foundation. The browser already knows how these elements should behave.
Focus states
Another detail that is often overlooked is focus styling.
When navigating with a keyboard the user needs to clearly see where they currently are on the page. Browsers provide a default focus outline, but many designs remove it for visual reasons.
Removing the focus outline without replacing it with something equally clear creates a frustrating experience for keyboard users.
A better approach is to style the focus state so it fits the design while still remaining very visible. This can be done with the :focus-visible selector which only shows the outline when keyboard navigation is used.
a:focus-visible,
button:focus-visible {
outline: 3px solid #22c55e;
outline-offset: 2px;
}
The important thing is clarity. The user should never have to guess which element currently has focus.
ARIA attributes only when necessary
ARIA attributes are powerful, but they are often misunderstood.
A common mistake is adding ARIA everywhere in an attempt to improve accessibility. In reality this can make things worse.
The first rule of ARIA is simple. If native HTML can express the behaviour, use native HTML.
For example a <button> already communicates that it is clickable and interactive. A <nav> element already describes a navigation landmark.
ARIA becomes useful when you build more complex components such as expandable menus or interactive widgets that do not exist as native HTML elements. In those cases attributes like aria-expanded, aria-controls, or aria-current can help assistive technologies understand what is happening.
<button
id="menu-toggle"
aria-expanded="false"
aria-controls="mobile-menu">
Menu
</button>
<nav id="mobile-menu" hidden>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
Used sparingly, ARIA improves clarity. Used excessively, it often introduces confusion.
Mobile menu accessibility pitfalls
Mobile navigation introduces a few additional challenges.
The common pattern is a button that opens and closes a menu. Visually this is simple, but accessibility details matter.
The menu button should be a real <button> element. It should communicate whether the menu is open by updating the aria-expanded attribute. Screen reader users rely on this information to understand the current state.
<script>
const button = document.getElementById("menu-toggle");
const menu = document.getElementById("mobile-menu");
button.addEventListener("click", () => {
const isOpen = button.getAttribute("aria-expanded") === "true";
button.setAttribute("aria-expanded", !isOpen);
menu.hidden = isOpen;
});
</script>
Another common issue is focus management. When the menu opens, keyboard users should be able to navigate through the menu items immediately. When the menu closes, focus should return to the button that opened it.
It is also important that the menu can be closed with the Escape key. This small detail improves usability significantly for keyboard users.
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
button.setAttribute("aria-expanded", "false");
menu.hidden = true;
button.focus();
}
});
Finally, remember that small screens do not automatically mean touch only. Many users still connect keyboards to tablets or use assistive technology on mobile devices.
Summary
Accessibility in navigation does not require complex solutions.
Use semantic HTML. Make sure everything works with a keyboard. Provide clear focus states. Add ARIA only when it is actually needed.
If these fundamentals are in place, your navigation will already be more accessible than a large portion of websites on the internet.
And just like the KISS principle mentioned earlier, simplicity often leads to the most robust solution.