Navbar
UiNavbar is a composable top navigation bar. Assemble it from brand, title, nav, link, avatar, and toggle sub-components. From 992px the links live in UiNavbarCollapse; below that the collapse is hidden and UiNavbarMobileMenu shows instead, usually with the avatar. Pair it with UiNavigationBar for mobile links.
Build a navbar
Nav groups go inside UiNavbarCollapse, which is what lays them out. UiNavbarLink renders its own list item; wrap anything else, such as the avatar, in UiNavbarItem.
<script setup lang="ts">
import { NuxtLink } from '#components'
</script>
<template>
<UiNavbar sticky aria-label="Top navigation">
<UiNavbarTitle title="Dashboard">
<template #brand>
<UiNavbarBrand :as="NuxtLink" to="/" text="Acme" logo="/logo.svg" />
</template>
</UiNavbarTitle>
<UiNavbarMobileMenu>
<UiNavbarAvatar src="/me.jpg" alt="Account" size="sm" @click="openMenu" />
</UiNavbarMobileMenu>
<UiNavbarCollapse>
<UiNavbarNav position="start">
<UiNavbarLink :as="NuxtLink" to="/docs" text="Docs" />
<UiNavbarLink :as="NuxtLink" to="/pricing" text="Pricing" />
</UiNavbarNav>
<UiNavbarNav position="end">
<UiNavbarItem>
<UiNavbarAvatar src="/me.jpg" alt="Account" @click="openMenu" />
</UiNavbarItem>
</UiNavbarNav>
</UiNavbarCollapse>
</UiNavbar>
</template>
The current-page link is highlighted from the router's exact-active class, so give nav links a router component through as. active only sets aria-current="page". The UiNavbarTitle text fades in once a sticky navbar is stuck to the top.
Toggle a sidebar
UiNavbarToggle drives UiSidebar. It is hidden below 1024px unless show-toggle-button is set, and collapsed follows the rail, so one boolean usually drives both the rail and the mobile drawer:
<template>
<UiNavbarToggle show-toggle-button :collapsed="collapsed" controls="main-sidebar" @toggle="collapsed = !collapsed" />
</template>
UiNavbar props
| Prop | Type | Default | Description |
|---|---|---|---|
sticky | boolean | false | Sticky positioning. |
fluid | boolean | false | Fluid (full-width) container. |
ariaLabel | string | 'Main navigation' | Landmark name. Give it a distinct name when a UiSidebar (same default) is on the page. |
customClass | string | string[] | Record<string, boolean> | null | — | Classes on nav.navbar, such as nav-island or nav-transparent. |
Sub-components
| Component | Key props |
|---|---|
UiNavbarBrand | logo, initials (shown without a logo), text, as, to / href; #link slot replaces the link |
UiNavbarTitle | title; #brand slot before the title, #title slot after it |
UiNavbarCollapse | Desktop region, hidden below 992px. Default slot for UiNavbarNav groups, or #start / #end slots that render the groups for you |
UiNavbarNav | position: 'start' sits after the brand, 'end' is pushed to the far edge. Only styled inside UiNavbarCollapse |
UiNavbarItem | customClass; wraps custom content such as a search field or the avatar (UiNavbarLink renders its own item) |
UiNavbarLink | text, to / href, as, active, disabled; #icon slot before the text |
UiNavbarAvatar | src, alt, size ('sm' / 'navbar'); emits click |
UiNavbarMobileMenu | Shown only below 992px; customClass |
UiNavbarToggle | collapsed, controls, collapseText, expandText, showToggleButton; emits toggle |
CSS variables
Set these on :root, or on any wrapper to restyle only the navbars inside it. Variants such as nav-island and nav-transparent keep their own background and radius. Hover and pressed backgrounds come from the shared state layer.
:root {
--cffy-navbar-bg-color: var(--cffy-surface-container-low);
--cffy-navbar-link-active-bg-color: var(--cffy-primary-a10);
--cffy-navbar-link-active-color: var(--cffy-on-primary);
}
| Variable | Default | Controls |
|---|---|---|
--cffy-navbar-bg-color | --cffy-background | Background |
--cffy-navbar-color | --cffy-on-background | Brand and title text color |
--cffy-navbar-shadow | none | Shadow |
--cffy-navbar-radius | --cffy-radius-none | Corner radius (links follow it) |
--cffy-navbar-padding-inline / --cffy-navbar-padding-block | 0 / --cffy-space-8 | Inner padding |
--cffy-navbar-margin-block-end | the block padding | Space below the navbar |
--cffy-navbar-min-height | 4.25rem | Minimum height |
--cffy-navbar-easing / --cffy-navbar-duration | --cffy-ease-emphasized / --cffy-duration-600 | Background and collapse transitions |
--cffy-navbar-brand-font-size / --cffy-navbar-brand-font-weight | --cffy-fs-sm / --cffy-fw-800 | Brand text |
--cffy-navbar-brand-size | 50px | Maximum logo width and height |
--cffy-navbar-brand-hover-color | --cffy-primary-a20 | Brand color on hover |
--cffy-navbar-title-font-size / --cffy-navbar-title-font-weight | --cffy-fs-sm / --cffy-fw-600 | Page title |
--cffy-navbar-link-color | --cffy-muted-a10 | Link text |
--cffy-navbar-link-hover-color | --cffy-primary-a10 | Hovered link text |
--cffy-navbar-link-active-color / --cffy-navbar-link-active-bg-color | --cffy-primary-a10 / --cffy-surface-container | Current-page link (its border follows the background) |
--cffy-navbar-link-font-size / --cffy-navbar-link-font-weight | --cffy-fs-xs / --cffy-fw-600 | Link text |
--cffy-navbar-link-radius | navbar radius + .5rem | Link corners |
--cffy-navbar-link-padding-inline / --cffy-navbar-link-padding-block | 0 (--cffy-space-8 from 992px) / --cffy-space-8 | Link padding |