Top-of-page banners (cookie consent, system maintenance, “what’s new”) are simple-looking but reveal interesting design questions: when to show, when to hide, how to persist dismissal, and how to avoid breaking the layout.
Functional requirements
- Top-of-page banner with message. Interviewers probe how you handle long text on narrow screens — truncate, wrap, or cap the length at authoring time. Keep the copy to one line where possible so the banner does not dominate the viewport on mobile.
- Optional CTA (Learn more, Update now). A CTA can be a link to another page or an action that triggers something in-app; either way, wire it to analytics so you can measure click-through against dismissals.
- Dismiss button. Give it a clear close affordance (an X plus an accessible label) and make dismissal the primary way a user removes the banner rather than forcing them to complete the CTA.
- Don’t reappear after dismiss (per user / device). This is the state question the whole design turns on — you need somewhere to record “this user closed banner #47” and a rule for whether that persists across devices.
- Different banner types (info, warning, success). The type drives both color and the semantics you expose to assistive tech, so treat it as a first-class field on the banner data, not a styling afterthought.
Architecture
Two components:
- Banner manager: determines which banner (if any) to show
- Banner UI: renders message, CTA, dismiss
The “always there” layout problem
Banner shifts everything below by its height. Solutions:
- Reserve space at top of layout (sticky banner area). The container keeps its height whether or not a banner is present, which avoids a layout shift (CLS) the moment the banner mounts or unmounts.
- Banner uses fixed positioning over content (overlap). Cheap to add, but it hides whatever sits under it — the top nav, a first heading — so you usually still need top padding on the page.
- Adjust scroll-to-top math to account for banner. Anchor links and “back to top” jumps land at the wrong offset if they assume the viewport starts at 0; subtract the banner height from your scroll targets.
Best: layout reserves space; banner pushes content down.
Dismiss persistence
Don’t show the same banner twice. Options:
- localStorage: simple, per device. Lose on private browsing.
- Cookie: server-readable. Subject to cookie consent rules.
- Server-side: synced across devices. Requires user account.
For most banners, localStorage is sufficient.
Banner types
- Informational: blue/neutral. “New feature available.”
- Warning: yellow. “Scheduled maintenance Friday.”
- Critical: red. “Security incident — change password.”
- Success: green. “Email verified.”
Targeting
Show different banners to different users:
- By tier: paid users see different banners than free. The manager needs the user’s plan at render time, so decide whether that comes from a token claim, an API call, or data already hydrated on the page.
- By page: only on dashboard. Scope banners to routes so a maintenance notice for the billing area does not follow the user everywhere, and so per-page dismissal stays independent.
- By time: only between two dates. Give each banner a start and end window and evaluate it against server time, not the client clock, which users can change.
- By feature flag: A/B test banners. Gate the banner behind a flag so you can roll it out gradually or split traffic, then compare click-through and dismiss rate across the variants.
Banner stacking
Two simultaneous banners — show both? Stack vertically? Or queue?
Usually: max one banner at a time. Priority order: critical > warning > info.
Accessibility
- Banner has
role="status"orrole="alert"based on severity. Usestatus(a polite live region) for info and success so it is announced without interrupting, andalert(assertive) for critical messages a screen reader user must hear immediately. - Dismiss button has explicit label (“Dismiss notification”). An icon-only X reads as nothing to a screen reader, so add an
aria-labelor visually hidden text that names what gets dismissed. - Banner does not steal keyboard focus. Injecting a banner should not move the user’s focus out from under them; let them tab to the CTA and dismiss button in normal document order.
- Color contrast meets WCAG AA. That means at least 4.5:1 for the message text against the banner background — the pale yellow and green fills are the ones that usually fail, so check them, not just the red.
Cookie consent banner
Special category. Legal compliance:
- Show before any tracking cookies are set
- Reject button must be as prominent as Accept (GDPR)
- Granular control (Necessary, Analytics, Marketing)
- Persist user choice (cookie or localStorage)
Most apps use a third-party CMP (Consent Management Platform): OneTrust, Cookiebot, Iubenda.
Common antipatterns
- Banner re-appears after dismiss. Almost always a persistence bug — the dismissal was written to memory only, or the read happens before the stored value loads, so the banner flashes back on the next navigation.
- Banner that reads “important update” but provides no useful info. Vague copy trains users to dismiss on sight, which then buries the one banner that actually matters. Say what changed and what to do.
- Cookie banner that does not actually block tracking. If analytics and marketing scripts fire before the user accepts, the banner is decoration and you are still non-compliant — the consent choice has to gate script loading.
- Banner overlapping critical UI (e.g., a button). Fixed-position banners are the usual culprit; verify the banner does not cover the top nav, a primary action, or a form field at any breakpoint.
Frequently Asked Questions
Where should the banner appear?
Top of page is conventional. Bottom slide-up (toast-style) for less-urgent. Avoid middle of content.
Can I A/B test banner messaging?
Yes. Standard A/B testing framework. Track click-through and dismiss rate per variant.
What about banner fatigue?
Cap frequency: at most one banner per session, or per user per week. Banners that always show get ignored.
Useful next steps:
