COMPONENTS / NAVIGATION
Top menu
Responsive site navigation using native HTML popovers and CSS. Desktop and mobile lists share the same links, with nested submenus at any depth. Clicking outside dismisses open menus without JavaScript.
Component API summary · Optional glass material
Navbar layouts
Set data-navbar on html, a parent section, or the navigation itself. It inherits through the page; a local data-navbar="standard" resets a parent choice. It only affects .top-menu, leaving sidebars unchanged.
| Value | Layout |
|---|---|
| standard | Default: brand left, links and actions right. |
| centered | Balanced desktop grid: brand left, links in the middle, actions right. |
| floating | Standard alignment in an inset surface with a 1rem outer margin and the shared page width limit. It scrolls normally; it is not fixed or sticky. |
| split | Central brand with the primary link group on the left and an optional second group or actions on the right. |
Split can use a second .menu-items.menu-desktop list inside .menu-actions. Combine both groups in the single mobile list. Each desktop list keeps its own hover glide and dropdown anchors. Group additional actions in .menu-actions to avoid overlapping grid cells. Desktop links wrap inside their allocated column; below 48rem every preset retains the existing Menu button and native mobile popovers. Split changes visual placement, so choose a logical DOM and keyboard order for your content rather than expecting CSS to reorder focus.
<html lang="en" data-navbar="centered">
<!-- All top menus inherit centered layout. -->
<nav class="top-menu" data-navbar="standard" aria-label="Local navigation">
<!-- This menu overrides the parent layout. -->
</nav>
</html>Use the markup
Copy the example above and replace its link destinations. Keep both lists in sync. Give each navigation a unique --re-menu-anchor CSS identifier for mobile positioning as shown in the example. Give each desktop dropdown list item a unique --re-menu-branch-anchor; its descendants inherit that identifier so nested panels remain beneath the visible top-level button. Every panel needs a unique document-wide id, and each toggle's popovertarget must match that id. Generate both layouts from a shared template. Nest child panels and their toggle buttons inside the parent panel so native dismissal preserves the hierarchy.
Structure and configuration
| Class or setting | Use |
|---|---|
.top-menu | Navigation landmark and containing surface. |
data-navbar | Inherited layout: standard (default), centered, floating, split. |
.menu-actions | Optional right-hand group for actions and a second desktop list. |
.menu-brand | Optional brand link. |
.menu-desktop | Desktop list, visible at 48rem and wider. |
.menu-collapse | Mobile Menu button, with class menu-toggle and popovertarget. |
.menu-items.menu-mobile | Mobile top-level list with a unique id and popover auto. |
.menu-dropdown | List item containing a toggle button and its submenu. |
.menu-toggle | Native type button control using popovertarget to toggle a panel. |
.menu-panel | Submenu list with a unique id and popover auto. |
.menu-back | List item containing a button with popovertargetaction hide, targeting its own panel. |
popover="auto" | Native outside-click and Escape dismissal. Another unrelated auto popover closes the current stack; descendants can remain open with their ancestors. |
aria-current="page" | Marks the current page link. |
--re-menu-branch-anchor | Unique CSS anchor identifier on each desktop dropdown list item; anchors that branch and its nested panels to the top-level toggle. Single panels can use the native implicit button anchor. |
--re-menu-width | Desktop panel width, default 20rem, bounded by the viewport. |
Responsive behavior
Below 48rem the Menu button opens a viewport-bounded panel. Nested panels replace the parent view; Back returns one level and Close menu dismisses the mobile stack. At 48rem and wider, CSS anchor positioning places each panel below its own top-level toggle button, with alternate positions near viewport edges. Nested panels replace the parent view on desktop too, keeping deep menus within one readable surface. Without CSS anchor positioning, panels remain usable as centered popovers.
The browser paints popovers in its top layer, so ancestor overflow does not clip them. The page remains scrollable and interactive. CSS hides panels belonging to the inactive layout when crossing the breakpoint; returning to that layout may restore its open state. Clicking outside or closing a parent dismisses its descendant panels.
Keyboard and accessibility
Tab and Shift+Tab move between visible links and buttons. Enter and Space activate toggle buttons. Escape closes the deepest open panel. Focus restoration follows the browser's native behavior; nested panels may not return focus to their opener. Use the visible Back controls to return through the hierarchy. Back and Close controls do not use autofocus, so opening by touch does not force a focus outline onto the first item. Tab moves into the browser's native popover focus order; keyboard focus indicators remain visible. The browser provides the toggle's expanded relationship through popovertarget; do not hard-code aria-expanded. Closed panel links leave the focus order. Use native navigation and list semantics, without application-menu roles or arrow-key expectations.
An outside click dismisses panels outside the clicked branch. Clicking a parent panel closes its deeper descendants while leaving that parent open. Clicking another unrelated menu closes the previous stack. An ordinary destination link inside a panel does not automatically hide it; a full page navigation replaces the document, while an in-page link can leave it open. Native popover support is required for this markup. Screen-reader and actual-device review remain release checks.
Gliding navigation highlight
The desktop top-level menu uses a shared rounded background that glides between hovered or visibly focused items, then returns to its current-page link when present. Nested and mobile lists use ordinary hover and focus styling without a gliding underline. Separate desktop menus keep independent highlight scopes. This default enhancement uses CSS anchor positioning and anchor-scope; ordinary hover, focus and current-page styling remain the fallback. When there is no current-page item, the first hover or keyboard focus displays the highlight directly at that item; moving between adjacent items glides it to the next. Parent data-motion controls duration, while reduced-motion preferences disable the glide. No JavaScript or extra class is required. The effect reserves ::after on the desktop menu-items list; it preserves the separate desktop branch anchors used for dropdown positioning.
Styling and modules
Shared theme, tone, density, shape, depth, border and control size settings continue to inherit. The optional glass stylesheet treats the panels as glass surfaces while navigation toggle buttons retain their neutral navigation appearance. Complete, scoped, component and dedicated navigation builds include the styles. Load reva.navigation.css after tokens and base modules; use the complete build for all accessibility utilities. Open panels and navigation are hidden in print.