Designer view

Banner

A region-wide persistent informational surface — typically pinned to the top of a page or section — that surfaces system-level notices, promotional content, or status messages that should be visible across the user's session. Distinct from Alert (contextual, bound to a specific situation) by its persistence and scope, from Toast (transient, corner-anchored) by its persistence and full width, and from Modal (blocking) by its non-blocking contract. Used for cookie consent, maintenance notices, beta-feature callouts, system-degradation warnings, and full-bleed promotional CTAs.

When to use

Use

For region-wide or page-wide persistent informational surfaces — cookie consent, maintenance notices, beta-feature callouts, system-degradation warnings, full-bleed promotional CTAs. Banner is non-blocking, persistent (survives navigation when configured), and visible across the user's session.

Avoid

For contextual situation-specific notices bound to a specific page or form — that is `Alert`. For transient confirmations after async actions — that is `Toast`. For blocking decisions or destructive confirmations — that is `Modal[variant=alertdialog]`. For on-demand description — that is `Tooltip`.

Versus related

  • alert

    `Alert` is contextual and bound to a specific situation (form error, recent action confirmation); `Banner` is page-wide / region-wide and persists across the session. Alert appears in response to an event; Banner persists as ongoing system signal.

  • toast

    `Toast` is corner-anchored, ephemeral, and action-triggered; `Banner` is region-wide, persistent, and system-pushed. They occupy opposite ends of the notification-permanence spectrum.

  • modal

    `Modal[variant=alertdialog]` is blocking and demands explicit response; `Banner` is non-blocking and persistent. Banner that needs to block the page is a redesign signal (use Modal); Modal that needs to persist across navigation is also a redesign signal (use Banner plus an in-page Modal triggered from it).

Highlight
Fig 1.1 · Banner · Designer view
Designer

Figma anatomy

Slot Figma type Hint
container frame Auto-layout horizontal frame at full inline-size; padding from container token
icon instance Icon component instance; glyph swap bound to variant
title text Heading text style; bound to a component property
body text Body text style; bound to a component property
actions frame Auto-layout horizontal frame containing button or link instances
dismiss-button instance Icon button instance; visibility bound to dismissible property
Designer

Token usage per slot

container
spacing
  • paddingspacing.compact
  • gapspacing.compact
color
  • backgroundcolor.surface.bg
  • bordercolor.border.subtle
icon
color
  • foregroundcolor.text.accent
title
color
  • foregroundcolor.text.primary
typography
  • sizetext.md
  • weightweight.semibold
body
color
  • foregroundcolor.text.primary
typography
  • sizetext.sm
  • lineHeightleading.normal
actions
spacing
  • gapspacing.tight
  • paddingspacing.tight
dismiss-button
spacing
  • paddingspacing.tight
radius
  • cornerradius.sm
color
  • foregroundcolor.text.muted
  • ringcolor.border.focus
Both

Figma ↔ Code property map

FigmaTypeCodeNotes
VariantVariantvariantMaps info / promotional / warning / error. Drives visual treatment plus icon glyph plus (where applicable) accessible role.
LayoutVariantlayouthorizontal / stacked. At and below `breakpoint.sm` the layout is forced to stacked regardless of authored value.
DismissibleBooleandismissibleToggles the dismiss-button slot visibility plus the dismiss event wiring.
PersistentBooleanpersistentControls whether the dismissed state survives page reload. True for one-time announcements (cookie consent, beta feature); false for session-only banners (maintenance that resolves at session end).
Has IconBooleanhasIcon
Has TitleBooleanhasTitle
TitleTexttitle
BodyTextbody
ActionsInstance SwapactionsSwap the actions slot — typically 1–3 Button or Link instances.
IconInstance SwapiconVariant-default icon glyph; designers may swap for domain-specific icons (e.g. a beta-tag icon for beta-feature banners).
Designer

Motion

TransitionDuration token
openmotion.duration.fast
closemotion.duration.fast
Easing
motion.easing.standard
Reduced motion
Instant (jump cut)
Designer

Responsive behaviour

BreakpointChange
breakpoint.smAt and below, the canonical layout switches from horizontal (icon · content · actions) to stacked (icon and title in row 1, body in row 2, actions in row 3 below). The container retains full-bleed inline-size; the dismiss button moves to the inline-end of the title row. For very narrow viewports, body prose may also wrap to more lines; banners exceeding 4 lines should be redesigned as Alert or Modal.
breakpoint.mdAbove this width, the layout property is honoured as authored. `horizontal` shows icon · content · actions inline; `stacked` retains the row-stacked layout regardless of available width.
Both

Internationalisation

RTL · mirroring

Banner inline layout follows logical direction — inline-start to inline-end ordering of icon · content · actions reverses visual position in RTL. Dismiss button moves to the visual left in RTL (still inline-end logically). Action button order reverses logically: primary action stays on inline-end (visual right in LTR, visual left in RTL). Variant icon glyphs are direction-neutral. Stacked layout is direction-neutral by inline-axis.

Text expansion

Title and body grow with translation; banner container inline-size is determined by parent (full bleed at document scope, region width at section scope), so growth wraps naturally to additional lines. Long-text languages (German, Russian, Finnish) routinely expand banner height by 20-30%; layout `stacked` accommodates better than `horizontal` for long text. Action button labels follow Button's expansion rules; multi-action banners may need to wrap actions to a second row under heavy expansion.

Both

Variants, properties, states

Variants

Structurally different versions of the component.

infopromotionalwarningerror

Properties

The same component, parameterised.

PropertyType
dismissibleboolean
persistentboolean
hasIconboolean
hasTitleboolean
layouthorizontal | stacked

States

Browser/user-driven (interactive) vs. app-driven (data).

KindStates
interactive
hoverfocus-visible
data
opendismissed
Both

State transitions

FromToTrigger
opendismissedUser clicks the dismiss button (when dismissible: true); or the consumer programmatically removes the banner; or the underlying system state resolves (e.g. maintenance window ends) and the consumer rehides the banner.
Both

Figma↔Code mismatches

  1. 01
    Figma

    A banner drawn full-screen, blocking the page

    Code

    A banner with `position: fixed` covering the viewport

    Consequence

    Designers may scale the banner to dominate the page for visual impact. Implementations following the Figma file ship a banner that visually blocks content, hides the navigation, and traps the user in a CTA they may not want to engage with. The pattern collapses to Modal but without Modal's a11y contract.

    Correct

    Banner is a region-wide horizontal strip, not a full-screen surface. If the surface needs to block the page, redesign as Modal (with proper focus trap and a11y contract). The canonical Banner caps height at one-to-three rows of content; tall banners are a redesign signal.

  2. 02
    Figma

    Cookie consent banner drawn with only an "Accept all" button

    Code

    Cookie consent banner with Accept-only — no Decline or Customise

    Consequence

    Designers may treat cookie banners as marketing surfaces with single CTA. Implementations following the design fail GDPR / ePrivacy compliance — users must be able to decline with a single action equally prominent as Accept.

    Correct

    For cookie consent banners specifically, the canonical action set requires Accept and Decline as visually equal. Customise / preferences may be a third option but never replaces Decline. Document the legal-compliance constraint explicitly; design review enforces it.

  3. 03
    Figma

    Banner sticky at top with no skip-link

    Code

    Banner pinned to viewport top with `position: sticky` consuming Tab focus

    Consequence

    Designers draw a sticky banner that visually persists across scroll. Developers ship it; keyboard users reach the banner first on every page-level Tab cycle (when banner contains tabbable content), and the visual sticky behaviour interacts with browser autoscroll-on-focus unpredictably.

    Correct

    Sticky banners require a skip-to-content link as the first focusable element after the banner (or before, depending on focus order). The canonical document-level skip-link already covers banners pinned at document scope; banners scoped to a region need a region-level skip-link.

  4. 04
    Figma

    Multiple banners stacked at the page top

    Code

    Multiple banners rendered, each in its own region

    Consequence

    Designers stack banners (cookie + beta-feature + maintenance + promotional) for visual mocks. Developers ship the stack; the page header is now half-banner, the user is overwhelmed, and the most recently-added banner is buried beneath legacy ones.

    Correct

    Cap the canonical banner stack at 1 visible banner at a time per scope (document-scope or region-scope). Beyond that, queue banners by priority — system-state banners (maintenance) outrank promotional banners; legal-compliance banners (cookie consent) outrank everything until acknowledged.

Designer

Common mistakes

#banner-as-modal

Banner sized to block the entire viewport

Problem

The banner is rendered at `100vh` or `position: fixed` with full-viewport coverage. Visually blocks the page; user cannot reach content beneath without dismissing or activating. The pattern claims Banner semantics (`role="region"`) while behaving like Modal.

Fix

Banner is a horizontal strip — top, bottom, or section- anchored — that does not visually block content beneath. If the surface genuinely needs to block, redesign as Modal with proper focus trap and `aria-modal`. Do not stretch Banner past one-to-three content rows.

#banner-multiple-stacked

Multiple banners stacked at the page top

Problem

Page renders cookie banner, beta-feature banner, maintenance banner, and promotional banner all at once. Visual hierarchy collapses; users either tune all out or miss the most important one (legal-compliance buried under promotional).

Fix

Cap the canonical banner display at 1 per scope at a time. Queue or prioritise by category: legal-compliance > system- state > beta-feature > promotional. Render the highest- priority banner; show others only after the higher- priority ones are acknowledged or dismissed.

#banner-dismissed-state-not-persisted

Dismissed banner reappears on every page load

Problem

User dismisses the banner; on the next navigation it reappears. The dismiss action feels meaningless; users learn to ignore the dismiss button entirely.

Fix

Persist the dismissed state for `persistent: true` banners — typically via localStorage keyed by banner id and version. Re-show only when the banner content changes (version bump) or when the consumer explicitly resets the dismissed state. For `persistent: false` banners (session- only), document the in-memory persistence contract.

#banner-color-only-variant

Variant differentiated by colour alone

Problem

The banner's variant is communicated only through background or border colour. Colour-vision deficient users cannot distinguish info from warning; the icon glyph and the text both fail to name the variant.

Fix

Triple-layer variant: visual (background / border / icon), explicit prose (the title or body names the variant — "Maintenance:", "Beta:", "Important:"), and where applicable accessible role. Colour alone is never the only differentiator.

Accessibility hints
Slot Accessibility hint
container Apply `role="region"` with an `aria-labelledby` reference to the title (or `aria-label` when no title is shown). For banners conveying urgent system state, `role="status"` (polite) is acceptable — `role="alert"` (assertive) is almost never appropriate for banner-scope content because the message is not action-required at the moment of appearance. Banner persists across navigation; do not re-announce on every route change.
icon Decorative — `aria-hidden="true"`. Variant intent is communicated through visible text and (where applicable) through `role`. Never rely on the icon glyph alone.
title Use a real heading element of an appropriate level relative to the surrounding document outline. The container's `aria-labelledby` references the title's id when present.
body Plain prose. Inline links (e.g. "Read our cookie policy") are valid in body prose; complex actions belong in the actions slot for keyboard reachability.
actions Buttons keep native semantics; links keep anchor semantics. Order primary first (visually inline-end on LTR; SR announces in DOM order). For cookie banners with legal-compliance requirements, "Decline" must be as prominent as "Accept" — visual weight equality is canonical.
dismiss-button Provide an accessible name ("Dismiss banner" or "Close notification"). Activation removes the banner from the document. Persistence (re-appears on next visit vs permanently dismissed) is a `persistent` property, documented separately.