Components · Banner
Components

Banner

A banner states a fact about the current state of a surface — not something that just happened, and not commentary inside prose. It is the only component allowed to span the full width of a page, which is why there is never more than one of them in view.

Which component is this?

Four components carry messages and they are not interchangeable. Choosing wrongly is the most common defect in review, so the test is written as a single question each.

ComponentAnswersLifetimePlacement
BannerWhat is true about this surface right now?As long as the fact is trueTop of the scope, full width
CalloutWhat should I know about this passage?Permanent — it is contentInline, in the flow
ToastWhat just happened?SecondsFloating, above everything
DialogWhat must I decide before continuing?Until answeredCentred, blocking

The giveaway for a misused banner is the past tense. “Your review was published” is a toast. “This event has not been verified” is a banner — it is still true on the next page load, and on the one after that.

Scopes

Two scopes exist and the difference is what the fact is about. A global banner is about the product; a scoped banner is about the one object on screen. They never appear together — if the product is degraded, nothing about a single event is worth saying.

Global

Above the header, edge to edge, about the whole product. Reserved for incidents, scheduled maintenance and policy changes that alter what the product does.

Ratings are read-only until 14:00 WET. We are migrating the review store. Existing ratings are unaffected.
PRODUCT HEADER, THEN THE PAGE

Scoped

Inside a surface, at the top of the object it describes. This is the one that carries product meaning for us: an unverified event, a closed rating window, an organiser's own page awaiting a claim.

This event was added by an athlete and has not been verified. It will not appear in regional rankings until an organiser claims it. Claim this event
Trail do Gerês 2026
12 Apr 2026 · Terras de Bouro

Tones

Neutral. A fact with no urgency — the default, and the right choice far more often than teams expect.
Warning. Something is degraded or time-bound. The user can still work, but the outcome may differ from normal.
Destructive. Something is broken or lost. Reserved for state the user cannot work around.

There is no success banner. Success is momentary by definition, and a persistent green bar telling someone their review published is still there tomorrow, still claiming it just happened. Success belongs to Toast.

Specification

PropertyValueWhy
Tonesneutral · warning · destructiveNo success, no primary — a banner is not a promotion
FillThe tone's -subtle tokenSolid tone fills at full width are the loudest thing a page can do
Boundary1px hairline, bottom only when globalThe system is flat; a banner separates with a line, never a shadow
Icon20px Lucide, tone-coloured, aria-hiddenRedundant with the text — colour is never the only signal
Radius0 when global, --radius-md when scopedA global banner is edge to edge; there is no corner to round
Max per scope1Two banners means neither is read
Rolerole="region" + aria-labelLandmark, not an alert — it did not just happen
DismissOnly when non-blocking; 44px targetA fact the user cannot act on must not be dismissible

Do & don't

Ratings for this event closed on 30 Apr 2026. You can still read reviews.
Do — state the fact, then what is still possible
Introducing our new rating experience — discover a smarter way to review events.
Don't — marketing. Two banned words in nine
We could not load 3 of 412 reviews. The average shown excludes them.
Do — say what the failure changed about what is on screen
Something went wrong. Please try again later.
Don't — names nothing, offers nothing, could be any page

Structure

<!-- Landmark, not an alert. A banner is state, not an event. -->
<div class="banner banner--neutral" role="region" aria-label="Event status">
  <span class="banner__icon" aria-hidden="true"><!-- lucide:info --></span>
  <div class="banner__body">
    <strong>This event has not been verified.</strong>
    It will not appear in regional rankings until an organiser claims it.
    <a href="/events/123/claim">Claim this event</a>
  </div>
  <!-- Only when the fact is non-blocking. Omit the button entirely otherwise. -->
  <button class="banner__dismiss" type="button" aria-label="Dismiss"></button>
</div>

Use role="status" instead of role="region" in the one case where a banner appears in response to something the user did — a failed background sync, say. Never role="alert": it interrupts whatever a screen reader is saying, which is only justified for something that has just gone wrong and is about to cost the user work.

Rules

  • One banner per scope. If two facts are true, the more severe one wins and the other waits. Stacking them trains people to skip the region.
  • Never a marketing surface. Every banned word from the anti-slop list applies here, and the Deletion Test applies harder: a banner that can be deleted without changing what the user understands about the page was never a banner.
  • Dismissal must persist — per user and per fact, not per session. A banner that returns on every navigation is worse than one that cannot be dismissed at all.
  • Non-blocking facts only may be dismissed. “This event is unverified” stays, because dismissing it would let someone read an unverified rating as a verified one.
  • No animation on entry. A banner is present when the page renders; sliding it in makes a static fact look like an event.
  • Links inside a banner are underlined, as everywhere else. Tone colour is not enough to mark a link inside a tone-coloured region.
Sporting Scouter Design System
Every token on this site is generated from theme.css.