Pular para o conteúdo

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.

Quando esta spec se aplica

Triggers primários

Todos os triggers

Corpo da especificação

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

PositionUseSurfaces
TopPage title + nav + primary actionsAll surfaces
BottomThumb-reach actions on mobile / tablet portraitMobile + 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

VariantHeightTitleWhen
Center-aligned64 pxCentered, single lineMobile, primary screen, simple title
Small64 pxLeft-aligned, single lineDefault for most screens
Medium112 pxLarge title below toolbar row, scrolls into row on overflowHero screen with strong identity
Large152 pxDisplay-style title with breathing roomBranded / 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

ModeBehavior
StaticTitle is text only
With subtitleTitle + 14 px subtitle below (small bar height 72 px)
With breadcrumbStack: breadcrumb above small title; OR replace title with full breadcrumb path
EditableTap 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

VariantOn scroll-downOn scroll-up
Small / CenterSurface tint deepens (elevation overlay) when content is belowTint clears at top
Medium / LargeTitle row collapses; toolbar staysTitle row expands back when at top
PinnedAlways visible (default)
Lift-on-scrollHidden on scroll-down past threshold; revealed on scroll-upRe-appears on scroll-up
Always-showNever 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 positionUse
RightDefault; thumb-reach for primary action
CenterSingle dominant action; bar holds 2 actions max each side
No FABBottom 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:

ClassTop barBottom bar
Compact (< 600 dp)Small + Center-alignedAllowed
Medium (600-839 dp)Small (medium for hero)Allowed (tablet portrait)
Expanded (840-1199 dp)Small / MediumForbidden (use side rail)
Large (≥ 1200 dp)Small / MediumForbidden (use drawer)

R8 — States

StateVisual
RestDefault colors
Scrolled content underneathSurface tint deepens (Material 3 elevation overlay), 3 dp tonal lift
Hovered (icon button)State layer 8% on icon hit area
PressedState layer 12%
Focused2 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 has aria-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

PresetTop barBottom bar
material3Tonal surface, no borderNotch flat, 24 dp corner
material2Flat color, 4 dp shadowFAB notch on bar
ios_cupertinoTranslucent blur, 1 px hairline borderTab bar pattern (not bottom app bar — re-map to nav bar)
gnomeHeaderbar style, integrated with window controlsNot used (desktop)
windows_11Mica backdrop, integrated title barNot used (desktop)
brutalistSolid color, no elevation, thick 4 px bottom borderSharp corners, no FAB cradle
terminal_classicSingle 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)
  • app-layout/safe-area.kmd — bottom bar must respect gesture-nav inset
  • app-layout/window-size-classes.kmd — adaptive per breakpoint
  • themes/elevation.kmd — scroll-state tonal overlay
  • themes/color-roles.kmdsurface-container token
  • interaction/states.kmd — icon button states
  • foundations/elements.kmd — Container family (bar) + Control family (actions)
  • components/navigation.kmd — sibling for primary navigation containers

Requirements (testable)

Requirement: Single top and single bottom bar per screen {#req-app-bars-single-instance}

A screen SHALL render at most one top app bar and at most one bottom app bar; two top bars SHALL NOT be stacked on the same screen, and any secondary toolbar SHALL be nested inside content instead.

Scenario: Second top bar is rejected

  • GIVEN a screen that already has one top app bar
  • WHEN a second top app bar is added to the same screen
  • THEN the layout is rejected as invalid
  • AND only one element with role="banner" exists in the screen

Scenario: One top and one bottom bar coexist

  • GIVEN a mobile screen
  • WHEN a top app bar and a bottom app bar are both mounted
  • THEN exactly one top bar and exactly one bottom bar are present
  • AND neither bar is duplicated

Requirement: Top bar variant heights and collapse {#req-app-bars-top-variants}

Top bar variants SHALL use their canonical heights (Center-aligned 64 px, Small 64 px, Medium 112 px, Large 152 px), and Medium and Large variants SHALL collapse their title into the toolbar row once scroll-y exceeds the title height.

Scenario: Medium variant collapses on scroll

  • GIVEN a Medium top app bar with height 112 px and content below it
  • WHEN the content is scrolled so scroll-y exceeds the title height
  • THEN the title row collapses and the title slides up into the toolbar row
  • AND the toolbar row remains visible

Scenario: Large variant expands back at top

  • GIVEN a Large top app bar collapsed after scrolling down
  • WHEN the content is scrolled back to scroll-y 0
  • THEN the title row expands back to the 152 px display-style layout

Scenario: Small variant renders at canonical height

  • GIVEN a Small top app bar
  • WHEN it is rendered
  • THEN its container height is 64 px with 16 px horizontal padding

Requirement: Visible action slot limits with overflow {#req-app-bars-action-slots}

A top app bar SHALL show at most 3 visible icon actions with additional actions moved into an overflow menu, and a bottom app bar SHALL show at most 4 icon actions.

Scenario: Fourth top-bar action moves to overflow

  • GIVEN a top app bar configured with 5 icon actions
  • WHEN the bar is rendered
  • THEN exactly 3 icon buttons are visible in the action area
  • AND the remaining actions appear inside the overflow () menu

Scenario: Fifth bottom-bar action is rejected

  • GIVEN a bottom app bar
  • WHEN a 5th icon action is added
  • THEN the configuration is rejected with at most 4 actions allowed

Requirement: Single scroll behavior per screen {#req-app-bars-scroll-behavior}

A screen SHALL apply exactly one top-bar scroll behavior (Pinned, Lift-on-scroll, or Always-show), and scroll behaviors SHALL NOT be mixed on the same bar.

Scenario: Lift-on-scroll hides then reveals

  • GIVEN a top app bar with Lift-on-scroll behavior
  • WHEN content is scrolled down past the hide threshold
  • THEN the bar hides
  • WHEN content is then scrolled back up
  • THEN the bar re-appears

Scenario: Mixing scroll behaviors is rejected

  • GIVEN a top app bar assigned the Pinned behavior
  • WHEN a second scroll behavior is also assigned to the same bar
  • THEN the configuration is rejected as invalid

Requirement: Bottom bar forbidden on expanded and large surfaces {#req-app-bars-surface-adaptation}

The bottom app bar SHALL be used only on Compact and Medium (tablet portrait) window-size classes, and SHALL NOT be rendered on Expanded (840–1199 dp) or Large (≥ 1200 dp) surfaces where actions move to a side rail or drawer.

Scenario: Bottom bar allowed on compact

  • GIVEN a Compact window-size class (< 600 dp)
  • WHEN a bottom app bar is requested
  • THEN the bottom app bar renders

Scenario: Bottom bar suppressed on expanded

  • GIVEN an Expanded window-size class (840–1199 dp)
  • WHEN a bottom app bar is requested
  • THEN the bottom app bar is not rendered
  • AND the actions are placed in the side rail instead

Requirement: App bar accessibility semantics {#req-app-bars-accessibility}

App bars SHALL expose correct roles and labels: the top bar container SHALL carry role="banner", every icon action SHALL have an aria-label, the overflow control SHALL be labelled "More actions", and keyboard focus order SHALL proceed nav → title → actions → overflow → FAB.

Scenario: Top bar exposes banner role and labelled actions

  • GIVEN a top app bar with a nav icon, title, two icon actions, and an overflow menu
  • WHEN the accessibility tree is inspected
  • THEN the container has role="banner"
  • AND each icon action has a non-empty aria-label
  • AND the overflow control has aria-label="More actions"

Scenario: Keyboard order follows nav to FAB

  • GIVEN a screen with a top app bar, actions, overflow, and an anchored FAB
  • WHEN the user tabs through focusable elements
  • THEN focus visits nav, then title (if focusable), then actions, then overflow, then FAB in that order

Referências