Search
Search
An inline notification block, with ten colour variants and an automatic horizontal layout when it leads with an icon.
An inline notification block.
<div class="alert alert-info">
<p class="alert-heading">Heads up</p>
<p>Your changes were saved.</p>
</div>
.alert-primary, .alert-secondary, .alert-brand, .alert-neutral, .alert-dark, .alert-light, .alert-success, .alert-danger, .alert-warning, .alert-info.
Each sets background, border and text colour from the matching -muted and -strong semantic tokens, so the pairing stays legible if the underlying colour changes.
.alert-success {
--alert-color-background: var(--color-success-muted);
--alert-color-border: var(--color-success-muted);
--alert-color-text: var(--color-success-strong);
}
.alert-primary and .alert-brand resolve identically, as do .alert-secondary and .alert-neutral. .alert-dark is the one exception to the muted pattern: it takes --color-text-on-dark rather than --color-dark-strong.
The base .alert declares no colours of its own, so an alert with no variant class shows whatever --alert-color-* resolves to in your token set.
--color-link is reassigned to the alert’s own text colour:
.alert { --color-link: var(--alert-color-text); }
Without that, a link inside a tinted block would fall back to the page link colour, which is chosen for contrast against the page background rather than against a muted tint.
An alert whose first child is an .icon, and which has no .alert-heading, switches to a horizontal layout on its own:
&:has(.icon:first-child):not(:has(.alert-heading)) {
flex-direction: row;
align-items: flex-start;
}
<div class="alert alert-warning">
<span class="icon icon-triangle-alert"></span>
<p>This action cannot be undone.</p>
</div>
With a heading present the alert stays stacked, because the icon then belongs beside the heading rather than beside the whole block. .alert-heading is itself a flex row with --spacing-xs between its children, so an icon inside the heading lines up with the text.
.container inside an alert.container inherits the same flex layout as the alert itself:
&,
.container {
display: flex;
flex-direction: var(--alert-direction, column);
gap: var(--alert-gap);
}
That is what lets a full-bleed alert keep its content aligned with the rest of the page: the alert spans the viewport, the container inside it caps the measure, and both lay their children out the same way.
.alert declares display: flex, which would otherwise beat the user agent rule for [hidden]. The file restores it:
.alert[hidden] { display: none; }
So a dismissible alert can be hidden with the attribute alone, with no state class to manage:
alert.hidden = true;
.alert * sets margin-block: 0 on every descendant, so paragraphs inside an alert are spaced by the flex gap rather than by their own margins. Vertical rhythm around the alert itself comes from --alert-margin.