Building Responsive Navigation with CSS and JavaScript

Responsive navigation is one of those front‑end jobs that looks simple until real content arrives.
The demo has five short links. The production site has two levels of navigation, long labels, account links, campaign links, and a content editor who quite reasonably wants to add another item later. The menu works at one breakpoint, then wraps awkwardly at another. JavaScript opens it nicely, until the script fails and the navigation disappears.
A good responsive navigation pattern starts by protecting the links.
Begin with a Real List of Links
The navigation should start as ordinary HTML.
That usually means a nav element, a list, and real anchors. Before adding collapse behaviour, check that the links are visible and usable in a simple layout.
The JavaScript layer can improve that experience:
- open and close a compact menu
- toggle sub‑navigation
- update button text or state
- trap accidental double opening
- close the menu when the user follows a link
But JavaScript should not be the reason the links exist. If a menu is empty until a script builds it, the baseline is weaker than it needs to be.
let CSS Handle Layout First
CSS should do as much of the responsive work as possible.
Media queries can switch between:
- a horizontal list on wide screens
- a wrapped list where space allows
- a compact disclosure pattern on narrow screens
- simpler spacing for cramped layouts
The article on media queries in CSS covers the mechanics. The important design decision is choosing breakpoints based on when the navigation actually stops fitting, not simply on device names.
"Tablet" and "mobile" are too vague. The menu cares about available width and content length.
Use a Button for Menu Toggles
If a control opens and closes the navigation, it is a button, not a link.
A link with href="#" and a click handler creates avoidable problems. It has no real destination, it can jump the page, and it says the wrong thing semantically.
Use a button with clear text. If the design uses an icon, keep a text label available for assistive technology. The button should also expose state, commonly with aria‑expanded, and reference the menu it controls where possible.
This is not just an accessibility detail. It makes the behaviour easier to reason about and test.
Avoid Hiding the Menu Too Early
A common progressive enhancement mistake is hiding the compact menu in CSS before JavaScript has loaded.
If CSS hides the navigation by default and JavaScript is responsible for revealing it, a script error can remove the site's main links. A safer approach is:
- render the navigation visibly by default
- add an enhancement class when JavaScript runs
- use that class to enable the collapsed behaviour
The article on progressive enhancement with jQuery covers this pattern in more detail. It applies just as well to plain JavaScript.
Think About overflow and Real Labels
Responsive navigation should be tested with real content, not placeholder labels.
Check:
- long section names
- many top‑level links
- translated labels, if relevant
- logged‑in and logged‑out states
- active states
- focus states
- zoomed text
The menu should not rely on every label being one word. It should also not rely on the client never adding a sixth item.
Keep Sub‑Navigation Deliberate
Dropdowns and nested menus are where responsive navigation often becomes fragile.
If a top‑level item both opens a submenu and links to a section page, the interaction becomes ambiguous. Touch devices make that worse because hover is not reliable.
Prefer a clear pattern:
- top‑level links navigate
- adjacent buttons open submenus
- submenu items are ordinary links
- open state is visible and keyboard reachable
This may look slightly less minimal, but it is easier to use and maintain.
That accessibility point becomes more important when navigation patterns move into shared components. Accessibility in reusable front‑end components covers the same kind of state, naming, and keyboard behaviour at component level.
Wrapping Up
Responsive navigation is not just a breakpoint exercise. It is a resilience exercise.
Start with real links in usable HTML. Let CSS handle layout. Use JavaScript to enhance state and interaction, not to create the only path through the site. Then test the menu with real labels, real breakpoints, keyboard navigation, and JavaScript unavailable.
Key Takeaways
- Navigation should begin as real links in usable HTML.
- CSS should handle layout before JavaScript adds behaviour.
- Menu toggles should be buttons with clear state.
- Do not hide navigation by default and rely on JavaScript to reveal it.
- Test with realistic labels, zoom, active states, and nested navigation.
Postscript
This article is part of an archive restored from a previous version of my website on 27 May 2026. The original publication date is accurate. The article has since been restored and lightly edited for formatting, imagery, broken links, and current internal references.