Banners
components specs/components/banners.kmd
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.
Quando esta spec se aplica
Triggers primários
- Add a banner
Todos os triggers
- Inform user of system state at the top of a page
- Offer an action on a persistent issue (cookie consent, outage)
- Show an inline announcement without modality
Corpo da especificação
Spec — Banners
Facet Visual of Koder Design. Material parity: https://m3.material.io/components/banners.
Where they fit
| Component | Modality | Persistence |
|---|---|---|
| Banner | Non-modal | Persistent until user dismisses / acts |
| Snackbar | Non-modal | Transient (4-10 s) |
| Dialog | 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
- Height: 54 px (single line) / 90 px (two lines) / auto
- Padding: 16 px vertical, 24 px horizontal
- Icon: 24 px, optional, leading
- Message:
body-medium(14/20, weight 400) - Actions: text buttons, trailing
- Border: 1 px bottom
outline-variant - Background:
surface-container-low
R1 — Variants by tone
| Tone | Use | Icon | Background |
|---|---|---|---|
| Info | General announcement | info (ⓘ) | surface-container-low |
| Warning | Action needed soon | warning (⚠) | warning-container |
| Error | Action needed now / degraded service | error (✕) | error-container |
| Success / promo | Positive announcement | check (✓) | success-container (extended) |
Color alone never carries meaning — always pair tone with icon + text.
R2 — Action rules
- 0 actions: dismiss-only banner; tap × at end OR auto-show dismiss after read
- 1 action: action + dismiss button (× icon at end)
- 2 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 |
|---|---|
| Top of page content (default) | One banner per page |
| Top of section | One banner scoped to a section |
| Inside 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
- Appear: slide-down from top edge (motion-medium, ~250 ms)
- Dismiss: fade-out + slide-up (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-anchored, slight translucency, dismiss as swipe-up gesture |
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
Referências
specs/foundations/elements.kmdspecs/themes/color-roles.kmdspecs/themes/elevation.kmdspecs/components/snackbars.kmdspecs/components/dialogs.kmd