A navigation bar is not responsive merely because it fits the shortest labels on one phone. It also needs to cope with translations, text enlargement, keyboard focus and the last item in the list. This tutorial builds a wrapping navigation first, then shows when a horizontal scroller is appropriate.
The downloadable example is plain HTML and CSS, so it can be opened without a build tool. The same markup fits a React component. The examples use real links and do not implement a custom ARIA menu: website navigation normally does not need desktop-application menu semantics.
Start with a list of destinations
<nav aria-label="Main">
<ul class="nav-links">
<li><a href="#overview" aria-current="page">Overview</a></li>
<li><a href="#implementation">Implementation details</a></li>
<li><a href="#accessibility">Accessibility and testing</a></li>
<li><a href="#contact">Contact the development team</a></li>
</ul>
</nav>aria-current="page" belongs on the current destination, not every highlighted item. For section links on one page, aria-current="location" may be more appropriate when you actively track the visible section; the static download omits automatic tracking.
List structure makes the group understandable without CSS. Meaningful link text also avoids needing a tooltip to explain a truncated word.
Let the content decide the height
.nav-links {
display: flex;
flex-wrap: wrap;
gap: .4rem;
list-style: none;
margin: 0;
padding: .4rem;
}
.nav-links li { min-width: 0; }
.nav-links a {
display: block;
padding: .7rem .9rem;
overflow-wrap: anywhere;
border-radius: .5rem;
color: inherit;
}
.nav-links a:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 2px;
}Avoid a fixed header height with overflow: hidden: a second row may exist but be inaccessible. If a sticky header becomes very tall after wrapping, switch to a disclosure button at a sensible content-driven breakpoint. The disclosure needs an expanded state and must leave its links reachable by keyboard.
The CSS flex-wrap reference describes how wrapping creates additional flex lines. It does not decide your reading order; keep source order and visual order aligned instead of rearranging important destinations with order.
When horizontal scrolling is reasonable
A secondary category strip can scroll horizontally when wrapping would dominate the screen. Keep the main navigation easy to discover, and provide a visible hint that more categories exist.
.category-links {
display: flex;
gap: .5rem;
overflow-x: auto;
padding: .5rem;
scroll-padding-inline: .5rem;
}
.category-links a {
flex: 0 0 auto;
white-space: nowrap;
padding: .7rem .9rem;
}Do not hide the scrollbar merely for appearance. Native scrolling already supports touch and usually reveals a focused link; verify this in each target browser. If custom arrow buttons are added, label them and keep touch, wheel and keyboard operation working. Do not intercept every arrow key on an ordinary navigation list.
For a modal mobile panel, use a scrollable interior with a dynamic-viewport maximum height. Keep the close control visible and allow Escape to close it. See the scroll-position tutorial for the separate body-lock problem.
Verify every destination
Serve the download, reduce the viewport to 320 CSS pixels, and replace the longest label with something twice as long. At 200% browser zoom, every link must remain visible or discoverably scrollable. Tab forward and backward; the focus outline must not be cut off by an overflow container.
Check at least one real touch device, a keyboard-only desktop session, and a screen reader's links or landmarks list. Test a long unbroken label as well as normal prose. Make sure navigation does not require hover to reveal its only route to a page.
The fixture has a structural test for its link count, focus styling and responsive rules. That catches accidental removal of safeguards, not a browser's actual layout; visual and assistive-technology testing remain required.
Tradeoffs
Wrapping is discoverable but can increase header height. Horizontal scrolling is compact but can conceal destinations. A disclosure reduces clutter but adds an interaction. Choose based on the information architecture rather than a preferred animation.
For navigation that needs to work across a larger product, React web application development covers the component and its surrounding user flow.
