Banners
Persistent informational bar at the top of a content region — carries a message and 1-2 actions. Material parity (`/components/banners`). Distinguished from snackbars (transient) and dialogs (modal); banners stay until dismissed and never block interaction.
Spec — Banners
Facet *isual*of Koder Design. Material parity: https://m3.material.io/components/banners.
Where they fit
| Component | Modality | Persistence |
|---|---|---|
| *anner* | Non-modal | Persistent until user dismisses / acts |
| *nackbar* | Non-modal | Transient (4-10 s) |
| *ialog* | Modal | Persistent until user dismisses |
Pick banner when: information requires action OR awareness over multiple page interactions, but does NOT need to block the user.
Anatomy
┌────────────────────────────────────────────────────────┐
│ ⓘ Your subscription expires in 3 days. │
│ Renew now to keep access. │
│ [Renew] [Dismiss] │
└────────────────────────────────────────────────────────┘
↑ ↑ ↑ ↑
icon message action1 action2- *eight* 54 px (single line) / 90 px (two lines) / auto
- *adding* 16 px vertical, 24 px horizontal
- *con* 24 px, optional, leading
- *essage*
body-medium(14/20, weight 400) - *ctions* text buttons, trailing
- *order* 1 px bottom
outline-variant - *ackground*
surface-container-low
R1 — Variants by tone
| Tone | Use | Icon | Background |
|---|---|---|---|
| *nfo* | General announcement | info (ⓘ) |
surface-container-low |
| *arning* | Action needed soon | warning (⚠) |
warning-container |
| *rror* | Action needed now / degraded service | error (✕) |
error-container |
| *uccess / promo* | Positive announcement | check (✓) |
success-container (extended) |
Color alone never carries meaning — always pair tone with icon + text.
R2 — Action rules
- * actions* dismiss
only banner; tap × at end OR autoshowdismiss after read
- * action* action + dismiss button (× icon at end)
- * actions* primary + secondary text buttons; no separate ×
(secondary serves as dismiss when labeled "Dismiss")
Maximum 2 visible actions. Don't put overflow menu in a banner.
R3 — Placement
| Placement | When |
|---|---|
| *op of page content*(default) | One banner per page |
| *op of section* | One banner scoped to a section |
| *nside list / form* | Inline banner about a specific item |
Never stack multiple banners. If multiple announcements pending, show the highest-priority one first; queue the rest after dismissal.
App bar sits ABOVE banner — banner anchors below the top app bar.
R4 — Persistence and state
- Banner stays visible across scroll (does not stick to viewport;
scrolls with content)
- Dismissal is REMEMBERED per user + per banner ID — don't re-show
the same dismissed banner unless conditions change
- For "cookie consent" or "system upgrade" type banners, document
re-show conditions explicitly
R5 — Animation
- *ppear* slide
down from top edge (motionmedium, ~250 ms) - *ismiss* fade
out + slideup (motion-fast, ~150 ms) - Content below shifts smoothly when banner appears / disappears
(no abrupt layout jump)
- Reduced motion: instant show / hide
R6 — Accessibility
role="status"(info) orrole="alert"(warning/error)aria-live="polite"(status) /assertive(alert)- Action buttons have full labels (not "Click here")
- Dismiss × button:
aria-label="Dismiss banner" - Keyboard: Tab into action buttons → dismiss button; Esc dismisses
(when allowed by banner type)
- Icon is decorative if message conveys tone in words —
aria-hidden
R7 — Mobile responsiveness
| Width | Behavior |
|---|---|
| ≥ 600 dp | Single row, actions trailing |
| < 600 dp | Two rows: message on top, actions on second row (left-aligned) |
Truncate to 2 lines max on Compact width; expand to fit when actions move to a separate row.
R8 — Density
| Density | Padding | Height (single line) |
|---|---|---|
| Compact | 12 px / 20 px | 48 px |
| Default | 16 px / 24 px | 54 px |
| Comfortable | 20 px / 28 px | 64 px |
R9 — Per-preset variation
| Preset | Visual |
|---|---|
material3 |
Tonal background by tone, no border, 24 px radius corners on rounded variant |
material2 |
Sharp corners, 1 px hairline border |
ios_cupertino |
Top |
gnome |
InfoBar style — flat tonal, 6 px border-radius |
windows_11 |
Mica backdrop tint, accent color border-left |
brutalist |
Solid color block, 4 px thick border, no rounded corners |
terminal_classic |
Border-style box ┌── INFO ───┐ ... └──[OK]─┘ |
R10 — Forbidden patterns
- ❌ Stacking multiple banners on one page
- ❌ Banner over modal (banner is non-modal; modal already blocks)
- ❌ Auto-dismissing banner with a timer (use snackbar instead)
- ❌ More than 2 actions
- ❌ Putting form inputs / interactive controls inside banner body
- ❌ Showing the same dismissed banner without user-visible state change
- ❌ Color-only tone signal (always pair with icon + words)
- ❌ Sticking banner to viewport on scroll (annoying; use snackbar
if must stay visible)
Cross-link
themes/color-roles.kmd— tonal container tokensthemes/elevation.kmd— banner sits at 0 dp (within surface)components/snackbars.kmd— transient siblingcomponents/dialogs.kmd— modal siblingfoundations/elements.kmd— Container + Marker families