09 • Patterns · Sticky banner

Sticky banner

Top-of-page alert that persists on scroll. ARIA role auto-switches: role=alert+aria-live=assertive for danger, role=status+aria-live=polite for info/success/warning.

Info (system status)

Scheduled maintenance tonight
Some AI-assisted features will be briefly unavailable from 02:00 to 02:30 UTC.

Success (confirmation)

Incident #4872 resolved
All sites are operational. Root cause analysis queued for review.

Warning (attention required)

Danger (emergency)

Usage

import { StickyBanner } from "@/components/patterns/sticky-banner"

<StickyBanner
  severity="danger"
  title="Active incident"
  description="Response team en route"
  action={<Button size="sm">Open response</Button>}
  onDismiss={() => setShow(false)}
/>

Accessibility

  • role="alert" + aria-live="assertive" for danger severity (interrupts screen reader).
  • role="status" + aria-live="polite" for other severities (queues after current speech).
  • Dismiss button has aria-label="Dismiss banner".
  • Icons are aria-hidden — severity is communicated via color + aria-live, not icon alt text.
  • Focus ring honors global 3px red outline on dismiss button when focused via keyboard.