App bars
components specs/components/app-bars.kmd
Horizontal bar anchored at the top or bottom of an application surface — holds page title, primary navigation actions, and contextual actions. Material parity (`/components/top-app-bar` and `/components/bottom-app-bar`). Covers center/small/medium/large top bar variants and the bottom bar with FAB integration.
When this spec applies
Primary triggers
- Implement a top app bar
- Implement a bottom app bar
All triggers
- Add a top toolbar with title + actions
- Embed contextual actions for the current screen
- Replace title bar with a scrollable header
- Add a thumb-reach action bar at the bottom of a mobile screen
Specification body
Spec — App bars
Facet Visual of Koder Design. Material parity: https://m3.material.io/components/top-app-bar and https://m3.material.io/components/bottom-app-bar.
2 anchor positions
| Position | Use | Surfaces |
|---|---|---|
| Top | Page title + nav + primary actions | All surfaces |
| Bottom | Thumb-reach actions on mobile / tablet portrait | Mobile + tablet portrait |
Always at most ONE top bar and ONE bottom bar per screen. Do not stack two top bars; nest a secondary toolbar inside content if needed.
R1 — Top bar variants
| Variant | Height | Title | When |
|---|---|---|---|
| Center-aligned | 64 px | Centered, single line | Mobile, primary screen, simple title |
| Small | 64 px | Left-aligned, single line | Default for most screens |
| Medium | 112 px | Large title below toolbar row, scrolls into row on overflow | Hero screen with strong identity |
| Large | 152 px | Display-style title with breathing room | Branded / landing-level screen |
Medium and Large COLLAPSE into Small on scroll: title slides up into the toolbar row at scroll-y > title-height. This is the canonical collapse pattern.
Anatomy (small top bar)
┌────────────────────────────────────────────────┐
│ ☰ Page title ◷ ⋮ 👤 │
└────────────────────────────────────────────────┘
↑ ↑ ↑ ↑ ↑
nav title action overflow user
- Height: 64 px
- Horizontal padding: 16 px
- Nav icon slot: 24 px icon, left edge, optional
- Title:
title-large(22/28, weight 500) - Action slots: up to 3 icon buttons + 1 overflow menu
- Container bg:
surface-container(light: tinted; dark: tonal)
R2 — Action slot rules
- Maximum 3 visible icon actions; rest into overflow (
⋮) - Order from left to right by frequency / importance
- Each action is a 24 px icon button with 48 × 48 px hit target
- Action labels live in tooltip (long-press on mobile, hover on desktop)
- Disable actions don't collapse — show at 38% opacity
R3 — Title behavior
| Mode | Behavior |
|---|---|
| Static | Title is text only |
| With subtitle | Title + 14 px subtitle below (small bar height 72 px) |
| With breadcrumb | Stack: breadcrumb above small title; OR replace title with full breadcrumb path |
| Editable | Tap title opens inline rename input (rare; for renameable doc/board screens) |
Never wrap title to a 2nd line in small/center. Truncate with ellipsis or use Medium/Large variant.
R4 — Scroll behavior
| Variant | On scroll-down | On scroll-up |
|---|---|---|
| Small / Center | Surface tint deepens (elevation overlay) when content is below | Tint clears at top |
| Medium / Large | Title row collapses; toolbar stays | Title row expands back when at top |
| Pinned | Always visible (default) | — |
| Lift-on-scroll | Hidden on scroll-down past threshold; revealed on scroll-up | Re-appears on scroll-up |
| Always-show | Never hides | — |
Pick ONE scroll behavior per screen; don't mix.
R5 — Bottom app bar (mobile primary)
Anatomy:
┌────────────────────────────────────────────────┐
│ ⌂ ⌥ ⌽ ⊕ │
└────────────────────────────────────────────────┘
↑ ↑ ↑ ↑
actions (left-aligned) FAB (right)
- Height: 80 px (includes 24 px FAB cradle space)
- Action slots: up to 4 icon buttons, left-aligned
- FAB cradle: right side, FAB sits on bar (notched on Material 2, flat on Material 3)
- Container bg:
surface-container - Elevation: 2 dp (sits above scrolling content)
Use bottom bar ONLY on mobile + tablet portrait. On larger surfaces, move actions to top bar or side rail.
R6 — Bottom bar + FAB
| FAB position | Use |
|---|---|
| Right | Default; thumb-reach for primary action |
| Center | Single dominant action; bar holds 2 actions max each side |
| No FAB | Bottom bar with up to 4 actions, no embedded FAB |
FAB anchored to bottom bar cradle stays visible when bar scrolls.
R7 — Surface adaptation
App bars MUST adapt per app-layout/window-size-classes.kmd:
| Class | Top bar | Bottom bar |
|---|---|---|
| Compact (< 600 dp) | Small + Center-aligned | Allowed |
| Medium (600-839 dp) | Small (medium for hero) | Allowed (tablet portrait) |
| Expanded (840-1199 dp) | Small / Medium | Forbidden (use side rail) |
| Large (≥ 1200 dp) | Small / Medium | Forbidden (use drawer) |
R8 — States
| State | Visual |
|---|---|
| Rest | Default colors |
| Scrolled content underneath | Surface tint deepens (Material 3 elevation overlay), 3 dp tonal lift |
| Hovered (icon button) | State layer 8% on icon hit area |
| Pressed | State layer 12% |
| Focused | 2 px focus ring around icon button |
| Disabled (action) | 38% opacity |
R9 — Accessibility
- Top bar:
role="banner"on container - Title: heading level matches page hierarchy (h1 on landing page)
- Nav icon:
aria-label="Open navigation"or specific verb - Actions: each icon has
aria-label; overflow hasaria-label="More actions" - Bottom bar:
role="navigation"if actions navigate; else no role - Keyboard order: nav → title (focusable if editable) → actions → overflow → FAB
- Skip-to-content link before app bar for screen readers
R10 — Per-preset variation
| Preset | Top bar | Bottom bar |
|---|---|---|
material3 | Tonal surface, no border | Notch flat, 24 dp corner |
material2 | Flat color, 4 dp shadow | FAB notch on bar |
ios_cupertino | Translucent blur, 1 px hairline border | Tab bar pattern (not bottom app bar — re-map to nav bar) |
gnome | Headerbar style, integrated with window controls | Not used (desktop) |
windows_11 | Mica backdrop, integrated title bar | Not used (desktop) |
brutalist | Solid color, no elevation, thick 4 px bottom border | Sharp corners, no FAB cradle |
terminal_classic | Single text line ═ Page Title ═ | Bottom row [F1] [F2] [F3] style |
R11 — Forbidden patterns
- ❌ Two top bars stacked on one screen
- ❌ Bottom bar on Expanded/Large window-size class
- ❌ More than 3 icon actions visible in top bar (use overflow)
- ❌ More than 4 actions in bottom bar
- ❌ Title that wraps to 2 lines in Small / Center variant
- ❌ Bottom bar without safe-area inset on iOS / Android gesture-nav
- ❌ Hiding action labels entirely (always provide tooltip +
aria-label) - ❌ Animating the title across the entire bar width on collapse (jarring)
Cross-link
app-layout/safe-area.kmd— bottom bar must respect gesture-nav insetapp-layout/window-size-classes.kmd— adaptive per breakpointthemes/elevation.kmd— scroll-state tonal overlaythemes/color-roles.kmd—surface-containertokeninteraction/states.kmd— icon button statesfoundations/elements.kmd— Container family (bar) + Control family (actions)components/navigation.kmd— sibling for primary navigation containers
References
specs/foundations/elements.kmdspecs/themes/elevation.kmdspecs/themes/color-roles.kmdspecs/interaction/states.kmdspecs/app-layout/safe-area.kmd