Alert

Inline message

Intent

Alert communicates an inline, persistent message without blocking the user's flow -- a banner above a form, a warning inside a settings panel, a success note after a save. It lives in the page; it doesn't float over it. For blocking confirmations, reach for dialog.

Alert supplies the theming (background, border, color, accent); the .media composition primitive supplies the figure-plus-body layout. Put both classes on the root and let each do its one job.

Basic usage

The canonical shape: .alert and .media on the root, an icon in .media-figure, title and text in .media-body. role="alert" announces the message to assistive tech.

The .media pairing is required, not an enhancement. Alert owns no layout CSS of its own -- without .media on the root, the figure and body stack vertically via normal block flow and the row loses its flex context. Both classes on the root is the minimum shape.

<div class="alert media" role="alert">
    <svg class="media-figure" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
        <circle cx="12" cy="12" r="10"></circle>
        <path d="M12 16v-4"></path>
        <path d="M12 8h.01"></path>
    </svg>
    <div class="media-body">
        <h4>Heads up</h4>
        <p>Your profile has unsaved changes. Save before leaving this page.</p>
    </div>
</div>

No .alert-icon, .alert-title, or .alert-body -- alert themes, .media lays out. The heading glyph aligns with the figure thanks to a line-height rule on headings inside .media-body, so no margin nudge is needed.

Alert Headers

The alert supports any header (h1, h2, h3, h4, h5, h6) to accommodate semantic and accessibility needs. However, it is set to a specific font-size and weight for consistency. Override that with the --alert-header-font-size and --alert-header-font-weight tokens.

<div class="alert media" role="alert" style="--alert-header-font-size: var(--step-0); --alert-header-font-weight: var(--font-weight-black);">
    <svg class="media-figure" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
        <circle cx="12" cy="12" r="10"></circle>
        <path d="M12 16v-4"></path>
        <path d="M12 8h.01"></path>
    </svg>
    <div class="media-body">
        <h4>Heads up</h4>
        <p>Your profile has unsaved changes. Save before leaving this page.</p>
    </div>
</div>

Variants

Color

Status tones remap the scoped tokens to the matching semantic color family. The default (no modifier) uses neutral surface and border tokens and reads as an announcement rather than a status.

Scheduled maintenance

The API will be read-only between 02:00 and 03:00 UTC on Sunday.

Changes saved

Your settings were applied a moment ago.

Approaching quota

You've used 90% of your monthly request allowance.

Payment failed

We couldn't charge the card on file. Update your billing details to keep your subscription active.

<div class="stack is-snug">
    <div class="alert media is-info">
        <svg class="media-figure" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
            <circle cx="12" cy="12" r="10"></circle>
            <path d="M12 16v-4"></path>
            <path d="M12 8h.01"></path>
        </svg>
        <div class="media-body">
            <h4>Scheduled maintenance</h4>
            <p>The API will be read-only between 02:00 and 03:00 UTC on Sunday.</p>
        </div>
    </div>
    <div class="alert media is-success">
        <svg class="media-figure" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
            <path d="M20 6 9 17l-5-5"></path>
        </svg>
        <div class="media-body">
            <h4>Changes saved</h4>
            <p>Your settings were applied a moment ago.</p>
        </div>
    </div>
    <div class="alert media is-warning">
        <svg class="media-figure" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
            <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3z"></path>
            <path d="M12 9v4"></path>
            <path d="M12 17h.01"></path>
        </svg>
        <div class="media-body">
            <h4>Approaching quota</h4>
            <p>You&#39;ve used 90% of your monthly request allowance.</p>
        </div>
    </div>
    <div class="alert media is-danger">
        <svg class="media-figure" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
            <circle cx="12" cy="12" r="10"></circle>
            <path d="m15 9-6 6"></path>
            <path d="m9 9 6 6"></path>
        </svg>
        <div class="media-body">
            <h4>Payment failed</h4>
            <p>We couldn&#39;t charge the card on file. Update your billing details to keep your subscription active.</p>
        </div>
    </div>
</div>

The icon in .media-figure inherits the variant's accent color, so the same SVG reads as informational, positive, cautionary, or destructive depending on the modifier.

Density

.is-compact tightens padding one tier (from ui-pad-*-snug to ui-pad-*-tight), tightens the figure-to-body gap, and drops the font size one step. Use it when an alert sits inside a dense panel -- a sidebar, a form with tight rhythm -- where the default padding would feel out of scale.

Draft autosaved

Changes are kept locally until you publish.

<div class="alert media is-compact is-warning">
    <svg class="media-figure" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
        <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3z"></path>
        <path d="M12 9v4"></path>
        <path d="M12 17h.01"></path>
    </svg>
    <div class="media-body">
        <h4>Draft autosaved</h4>
        <p>Changes are kept locally until you publish.</p>
    </div>
</div>

Without a figure

The .media-figure slot is optional. Drop it and .media-body fills the row. Use for text-only announcements where an icon would be redundant -- a short status line, a plain-language confirmation.

<div class="alert media is-info" role="alert">
    <div class="media-body">
        <h4>New keyboard shortcuts</h4>
        <p>Press ? anywhere in the app to see the full shortcut list.</p>
    </div>
</div>
<div class="alert media is-info" role="alert">
    <div class="media-body">
        <p>A message alert only</p>
    </div>
</div>

Dismissible

Add data-dismissible to the alert root and drop a <button class="dismiss"> inside. The unified dismiss behavior (see dismiss) walks up from the clicked button to the nearest [data-dismissible] ancestor and removes it. No alert-specific JavaScript.

<div class="alert media is-info" role="alert" data-dismissible="">
    <svg class="media-figure" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
        <circle cx="12" cy="12" r="10"></circle>
        <path d="M12 16v-4"></path>
        <path d="M12 8h.01"></path>
    </svg>
    <div class="media-body">
        <h4>Tip</h4>
        <p>You can drag columns to reorder them. This message won&#39;t come back after you close it.</p>
    </div>
    <button class="dismiss" type="button" aria-label="Close">×</button>
</div>

The dismiss button lives as a third child inside the .media row; it doesn't need its own slot class. aria-label="Close" gives it an accessible name since the × glyph alone is not announced meaningfully.

Class reference

  • .alert -- the alert root. Pair with .media for the figure-plus-body layout.
  • .is-info, .is-success, .is-warning, .is-danger -- color variants. Remap the four theming tokens to the matching semantic family.
  • .is-compact -- density variant. Tightens padding, gap, and font size one tier.

Customization

Alert's scoped tokens split into two groups: four theming tokens (background, color, border, accent) and a padding pair. Color variants remap the theming tokens to the matching semantic family; .is-compact tightens the padding pair. Alert also remaps --media-gap locally so the figure-to-body pair sits tighter than the generic .media default -- override on a single element to loosen it again without disturbing other tokens.

Full token list and defaults: src/css/alert.css.

Accessibility

  • Pick the right live-region role. Use role="alert" for messages that should interrupt the user -- an error that must be acted on, a failure notice. Use role="status" for passive updates -- "saved", "loaded" -- that can wait for a pause in screen-reader speech. Omit both for messages that are already part of the surrounding flow (a help note inside a form field, for example).
  • Name the dismiss button. The × glyph is not announced as "close" by default. aria-label="Close" (or a localized equivalent) gives the button an accessible name.
  • Warning-text contrast. --color-warning-text uses a darker palette stop than the other status-text tokens -- yellow against a subtle background needs the extra stop to pass AA. Intentional; no override needed.

CSS Reference: Alert

Inline persistent message

Source: src/css/alert.css

Tokens

TokenDefaultDescription
--alert-bgvar(--color-surface-raised)The background color for the alert
--alert-header-font-sizevar(--step-0)The font-size for the alert header
--alert-header-font-weightvar(--font-weight-bold)Font weight for the alert header
--alert-colorvar(--color-text)Text color for the alert body and header
--alert-bordervar(--color-border)Border color for the alert container
--alert-accentvar(--color-border-strong)Accent color used for the icon and left-border emphasis
--alert-padding-blockvar(--ui-pad-y-snug)Vertical padding inside the alert
--alert-padding-inlinevar(--ui-pad-x-snug)Horizontal padding inside the alert
--media-gapvar(--gap-snug)Gap between the icon figure and body content

Slots

SlotDescription
.media-figureIcon slot, colored by the active accent

Classes

ClassDescription
.alertcomponent root
.is-infoInfo color variant for primary-tone alerts
.is-successSuccess color variant
.is-warningWarning color variant
.is-dangerDanger color variant
.is-compactTighter padding and gap for dense layouts