Bottom Navigation
Material Design 3 bottom navigation component for mobile-first navigation
Bottom Navigation
Bottom navigation bars allow users to navigate between primary destinations in an app. @duskmoon-dev/core provides a complete Material Design 3 bottom navigation implementation with support for icons, labels, badges, and multiple display modes.
Basic Usage
Basic Bottom Navigation
<nav class="bottom-nav">
<a href="#" class="bottom-nav-item bottom-nav-item-active">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<span class="bottom-nav-label">Search</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<span class="bottom-nav-label">Profile</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span class="bottom-nav-label">Settings</span>
</a>
</nav>Active States
Primary Active (Default)
The default active state uses the secondary container color:
Primary Active State
<nav class="bottom-nav">
<a href="#" class="bottom-nav-item bottom-nav-item-active">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<span class="bottom-nav-label">Search</span>
</a>
</nav>Secondary Active
Use the secondary color scheme for active items:
Secondary Active State
<a href="#" class="bottom-nav-item bottom-nav-item-active-secondary">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>Tertiary Active
Use the tertiary color scheme for active items:
Tertiary Active State
<a href="#" class="bottom-nav-item bottom-nav-item-active-tertiary">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>Navigation Items with Badges
Numeric Badges
Show notification counts with numeric badges:
Numeric Badge
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
<span class="bottom-nav-label">Notifications</span>
<span class="bottom-nav-badge">5</span>
</a>Dot Badges
Use dot badges for simple notification indicators:
Dot Badge
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
<span class="bottom-nav-label">Messages</span>
<span class="bottom-nav-badge bottom-nav-badge-dot"></span>
</a>Display Modes
Labels Only Mode
Show only labels without icons for a text-based navigation:
Labels Only Mode
<nav class="bottom-nav bottom-nav-labels-only">
<a href="#" class="bottom-nav-item bottom-nav-item-active">
<span class="bottom-nav-label">Home</span>
</a>
<a href="#" class="bottom-nav-item">
<span class="bottom-nav-label">Search</span>
</a>
<a href="#" class="bottom-nav-item">
<span class="bottom-nav-label">Profile</span>
</a>
<a href="#" class="bottom-nav-item">
<span class="bottom-nav-label">Settings</span>
</a>
</nav>Shift Mode
In shift mode, labels only appear on the active item:
Shift Mode
<nav class="bottom-nav bottom-nav-shift">
<a href="#" class="bottom-nav-item bottom-nav-item-active">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<span class="bottom-nav-label">Search</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<span class="bottom-nav-label">Profile</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span class="bottom-nav-label">Settings</span>
</a>
</nav>Surface Variants
Default Surface
The default surface uses the surface-container color:
Default Surface
<nav class="bottom-nav">
<!-- Navigation items -->
</nav>Surface
Use the base surface color:
Surface
<nav class="bottom-nav bottom-nav-surface">
<!-- Navigation items -->
</nav>Surface Container Low
Use a lower elevation surface:
Surface Container Low
<nav class="bottom-nav bottom-nav-surface-container-low">
<!-- Navigation items -->
</nav>Surface Container High
Use a higher elevation surface with shadow:
Surface Container High
<nav class="bottom-nav bottom-nav-surface-container-high">
<!-- Navigation items -->
</nav>Transparent
Create a transparent bottom navigation:
Transparent
<nav class="bottom-nav bottom-nav-transparent">
<!-- Navigation items -->
</nav>Size Variants
Compact
A more compact navigation bar with reduced spacing:
Compact Size
<nav class="bottom-nav bottom-nav-compact">
<a href="#" class="bottom-nav-item bottom-nav-item-active">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<span class="bottom-nav-label">Search</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<span class="bottom-nav-label">Profile</span>
</a>
</nav>Border Variants
Borderless
Remove the top border:
Borderless
<nav class="bottom-nav bottom-nav-borderless">
<!-- Navigation items -->
</nav>States
Disabled Items
Disable specific navigation items:
Disabled Item
<a href="#" class="bottom-nav-item bottom-nav-item-disabled">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<span class="bottom-nav-label">Disabled</span>
</a>Best Practices
Navigation Structure
Bottom navigation is best for:
- 3-5 top-level destinations
- Mobile and tablet interfaces
- Destinations of equal importance
Navigation Structure
<!-- Good: 3-5 items -->
<nav class="bottom-nav">
<a href="#" class="bottom-nav-item bottom-nav-item-active">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<span class="bottom-nav-label">Search</span>
</a>
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<span class="bottom-nav-label">Profile</span>
</a>
</nav>Accessibility
Always ensure proper accessibility:
Accessibility Example
<!-- Good: Semantic HTML with proper ARIA attributes -->
<nav class="bottom-nav" role="navigation" aria-label="Primary navigation">
<a
href="#home"
class="bottom-nav-item bottom-nav-item-active"
aria-current="page"
>
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>
<a href="#search" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<span class="bottom-nav-label">Search</span>
</a>
<a href="#notifications" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
<span class="bottom-nav-label">Notifications</span>
<span class="bottom-nav-badge" aria-label="3 unread notifications">3</span>
</a>
</nav>Label Guidelines
- Keep labels short (1-2 words)
- Use clear, unambiguous terms
- Ensure labels are always visible or use shift mode
Label Guidelines
<!-- Good: Short, clear labels -->
<span class="bottom-nav-label">Home</span>
<span class="bottom-nav-label">Search</span>
<span class="bottom-nav-label">Profile</span>
<!-- Avoid: Long labels -->
<span class="bottom-nav-label">User Profile Settings</span>Touch Targets
Navigation items are automatically sized for touch interfaces (minimum 64×48px):
Touch Targets
<!-- Touch targets are automatically optimized -->
<a href="#" class="bottom-nav-item">
<svg class="bottom-nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="bottom-nav-label">Home</span>
</a>Framework Examples
React
interface BottomNavItemProps {
icon: React.ReactNode;
label: string;
href: string;
active?: boolean;
badge?: string | number;
disabled?: boolean;
variant?: 'primary' | 'secondary' | 'tertiary';
}
function BottomNavItem({
icon,
label,
href,
active,
badge,
disabled,
variant = 'primary'
}: BottomNavItemProps) {
const activeClass = active
? variant === 'primary'
? 'bottom-nav-item-active'
: `bottom-nav-item-active-${variant}`
: '';
const disabledClass = disabled ? 'bottom-nav-item-disabled' : '';
return (
<a
href={href}
className={`bottom-nav-item ${activeClass} ${disabledClass}`.trim()}
aria-current={active ? 'page' : undefined}
>
<span className="bottom-nav-icon">{icon}</span>
<span className="bottom-nav-label">{label}</span>
{badge && (
<span className={`bottom-nav-badge ${typeof badge === 'string' && badge === '' ? 'bottom-nav-badge-dot' : ''}`}>
{badge}
</span>
)}
</a>
);
}
interface BottomNavigationProps {
children: React.ReactNode;
mode?: 'default' | 'shift' | 'labels-only';
surface?: 'default' | 'surface' | 'surface-container-low' | 'surface-container-high' | 'transparent';
compact?: boolean;
borderless?: boolean;
}
function BottomNavigation({
children,
mode = 'default',
surface = 'default',
compact = false,
borderless = false
}: BottomNavigationProps) {
const modeClass = mode !== 'default' ? `bottom-nav-${mode}` : '';
const surfaceClass = surface !== 'default' ? `bottom-nav-${surface}` : '';
const compactClass = compact ? 'bottom-nav-compact' : '';
const borderlessClass = borderless ? 'bottom-nav-borderless' : '';
return (
<nav
className={`bottom-nav ${modeClass} ${surfaceClass} ${compactClass} ${borderlessClass}`.trim()}
role="navigation"
aria-label="Primary navigation"
>
{children}
</nav>
);
}
// Usage
<BottomNavigation mode="shift" surface="surface-container-high">
<BottomNavItem
href="#home"
icon={<HomeIcon />}
label="Home"
active
/>
<BottomNavItem
href="#search"
icon={<SearchIcon />}
label="Search"
/>
<BottomNavItem
href="#notifications"
icon={<BellIcon />}
label="Notifications"
badge={3}
/>
<BottomNavItem
href="#profile"
icon={<UserIcon />}
label="Profile"
/>
</BottomNavigation>
Vue
<template>
<nav
:class="navClasses"
role="navigation"
aria-label="Primary navigation"
>
<slot />
</nav>
</template>
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
mode?: 'default' | 'shift' | 'labels-only'
surface?: 'default' | 'surface' | 'surface-container-low' | 'surface-container-high' | 'transparent'
compact?: boolean
borderless?: boolean
}
const props = withDefaults(defineProps<Props>(), {
mode: 'default',
surface: 'default',
compact: false,
borderless: false
})
const navClasses = computed(() => {
return [
'bottom-nav',
props.mode !== 'default' && `bottom-nav-${props.mode}`,
props.surface !== 'default' && `bottom-nav-${props.surface}`,
props.compact && 'bottom-nav-compact',
props.borderless && 'bottom-nav-borderless'
].filter(Boolean).join(' ')
})
</script>
<!-- BottomNavItem.vue -->
<template>
<a
:href="href"
:class="itemClasses"
:aria-current="active ? 'page' : undefined"
>
<span class="bottom-nav-icon">
<slot name="icon" />
</span>
<span class="bottom-nav-label">{{ label }}</span>
<span
v-if="badge !== undefined"
:class="badgeClasses"
:aria-label="badgeLabel"
>
{{ badge }}
</span>
</a>
</template>
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
href: string
label: string
active?: boolean
badge?: string | number
disabled?: boolean
variant?: 'primary' | 'secondary' | 'tertiary'
}
const props = withDefaults(defineProps<Props>(), {
active: false,
disabled: false,
variant: 'primary'
})
const itemClasses = computed(() => {
return [
'bottom-nav-item',
props.active && (
props.variant === 'primary'
? 'bottom-nav-item-active'
: `bottom-nav-item-active-${props.variant}`
),
props.disabled && 'bottom-nav-item-disabled'
].filter(Boolean).join(' ')
})
const badgeClasses = computed(() => {
return [
'bottom-nav-badge',
props.badge === '' && 'bottom-nav-badge-dot'
].filter(Boolean).join(' ')
})
const badgeLabel = computed(() => {
if (typeof props.badge === 'number') {
return `${props.badge} unread notifications`
}
return undefined
})
</script>
<!-- Usage -->
<BottomNavigation mode="shift" surface="surface-container-high">
<BottomNavItem href="#home" label="Home" :active="true">
<template #icon>
<HomeIcon />
</template>
</BottomNavItem>
<BottomNavItem href="#search" label="Search">
<template #icon>
<SearchIcon />
</template>
</BottomNavItem>
<BottomNavItem href="#notifications" label="Notifications" :badge="3">
<template #icon>
<BellIcon />
</template>
</BottomNavItem>
<BottomNavItem href="#profile" label="Profile">
<template #icon>
<UserIcon />
</template>
</BottomNavItem>
</BottomNavigation>
API Reference
Class Names
| Class | Description |
|---|---|
.bottom-nav | Base bottom navigation container (required) |
.bottom-nav-item | Individual navigation item (required) |
.bottom-nav-item-active | Active state with primary/secondary container color |
.bottom-nav-item-active-primary | Active state with primary/secondary container color (explicit) |
.bottom-nav-item-active-secondary | Active state with secondary container color |
.bottom-nav-item-active-tertiary | Active state with tertiary container color |
.bottom-nav-item-disabled | Disabled navigation item |
.bottom-nav-icon | Icon container |
.bottom-nav-label | Label text |
.bottom-nav-badge | Notification badge |
.bottom-nav-badge-dot | Dot-style badge indicator |
.bottom-nav-labels-only | Show only labels without icons |
.bottom-nav-shift | Labels only show on active item |
.bottom-nav-surface | Base surface background |
.bottom-nav-surface-container-low | Low elevation surface |
.bottom-nav-surface-container-high | High elevation surface with shadow |
.bottom-nav-transparent | Transparent background |
.bottom-nav-compact | Compact size variant |
.bottom-nav-borderless | Remove top border |
Combinations
You can combine classes for different effects:
Class Combinations
<!-- Compact navigation with high elevation and no border -->
<nav class="bottom-nav bottom-nav-compact bottom-nav-surface-container-high bottom-nav-borderless">
<!-- Navigation items -->
</nav>
<!-- Shift mode with transparent background -->
<nav class="bottom-nav bottom-nav-shift bottom-nav-transparent">
<!-- Navigation items -->
</nav>
<!-- Labels-only with compact sizing -->
<nav class="bottom-nav bottom-nav-labels-only bottom-nav-compact">
<!-- Navigation items -->
</nav>