On this page
CSS Navbar and Dropdown Menus: Responsive, Sticky and Accessible Navigation
What is a navbar?
A CSS navbar is the main navigation area of a website. It holds the logo, links and sometimes actions like search or login. A dropdown menu reveals extra links when the user activates a parent item. Navigation is one of the most used UI components, so it must be fast, responsive and fully usable with keyboard and screen readers.
Focus keyword: CSS navbar dropdown. Related trending keywords: responsive navbar CSS, sticky header, mobile hamburger menu, accessible dropdown menu, :focus-within, aria-expanded, details summary menu, Popover API menu.
Semantic HTML for navigation
- Wrap primary navigation in
<nav aria-label='Main'>. If there are multiple navs on a page, give each a different label. - Use a list:
<ul><li><a href>. It gives screen reader users the item count. - Mark the current page with
aria-current='page'and style it with[aria-current='page']. - Provide a skip link (
Skip to main content) as the first focusable element.
Building the layout
Use flexbox: display: flex; align-items: center; gap: 16px; and push groups apart with margin-inline-start: auto. For a sticky header use position: sticky; top: 0; z-index: 100; and a background color so content does not show through. Use scroll-padding-top on html so anchor links are not hidden behind it.
Responsive navigation
On small screens, collapse links behind a menu button. The button must be a real <button> with aria-expanded and aria-controls, and JavaScript toggles the state. Design mobile first: show the menu button by default and reveal the inline links with a min-width media query or container query.
Dropdown approaches
- CSS-only with :hover and :focus-within: quick, works for keyboard because
:focus-withinkeeps it open while focus is inside. Weakness: hover-only menus are hard on touch devices and pointer users can lose the menu if there is a gap between the trigger and the panel. - Disclosure pattern (recommended): a
<button aria-expanded>toggles a list of links. Close on Escape and when focus or clicks move outside. This is simple and accessible. - details and summary: built-in toggle behavior with no JavaScript. Style the marker and position the panel absolutely.
- Popover API: use
popoverandpopovertargetfor a top-layer panel with light dismiss. Pair with anchor positioning as progressive enhancement.
Avoid role='menu' for site navigation. That role expects application-style arrow key behavior and often makes website navigation worse. A list of links inside a disclosure is usually the right choice.
Positioning the dropdown panel
Make the parent position: relative and the panel position: absolute; top: 100%; left: 0; min-width: 200px. Add z-index, a shadow and rounded corners. Use a small padding-top or a pseudo-element bridge so the pointer does not cross a dead gap.
Keyboard and focus checklist
- Tab moves through links and the dropdown button in a logical order.
- Enter and Space activate the button.
- Escape closes the dropdown and returns focus to the button.
- Focus is always visible with
:focus-visible. - Hidden panels must not be focusable: use
hidden,display: noneorvisibility: hidden.
Performance and motion
Animate opacity and transform, not height or top. Use @starting-style with transition-behavior: allow-discrete for entry and exit animation of display. Respect prefers-reduced-motion.
Quick summary
Use semantic nav and lists, a flex layout, a mobile menu button with aria-expanded and a disclosure dropdown that supports keyboard and outside click. That produces a reliable CSS navbar dropdown.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Complete the dropdown. The button must toggle aria-expanded and the hidden attribute of the list, close on Escape and return focus to the button, and close when the user clicks outside. The focus style must be visible.
Press Run to execute.
Show expected output
Clicking the button opens the list and updates aria-expanded. Escape or an outside click closes it and Escape returns focus to the button.This is a self-check — compare your result with the expected output above.
Was this page helpful?