Inline Alert
A static status message in four severities, sitting in the flow.
6 frameworksBeginner
A closable status message that hands focus somewhere sensible.
<!--
Dismissal is a focus problem before it is a styling problem.
When the close button removes its own alert, the focused element leaves the
DOM. The browser's fallback is to drop focus onto <body> - which strands
keyboard users at the very top of the page, having lost their place entirely.
Move focus somewhere sensible FIRST, then remove.
The other half: the accessible name has to say what it closes. Twelve buttons
all called "Dismiss" are indistinguishable in a screen reader's list.
-->
<div class="alert-x" role="status">
<svg class="alert-x__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path d="M10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm1 4a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-2 3a1 1 0 0 1 2 0v5a1 1 0 1 1-2 0V9Z" />
</svg>
<div class="alert-x__body">
<p class="alert-x__title">Scheduled maintenance</p>
<p class="alert-x__text">We'll be read-only on Sunday 03:00-04:00 UTC.</p>
</div>
<button class="alert-x__close" type="button" aria-label="Dismiss: Scheduled maintenance">
<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path d="M6.3 6.3a1 1 0 0 1 1.4 0L10 8.6l2.3-2.3a1 1 0 1 1 1.4 1.4L11.4 10l2.3 2.3a1 1 0 0 1-1.4 1.4L10 11.4l-2.3 2.3a1 1 0 0 1-1.4-1.4L8.6 10 6.3 7.7a1 1 0 0 1 0-1.4Z" />
</svg>
</button>
</div>
<script>
document.querySelector('.alert-x__close').addEventListener('click', (event) => {
const alert = event.currentTarget.closest('.alert-x');
// Hand focus to a stable neighbour before the button stops existing.
const next = alert.nextElementSibling ?? alert.parentElement;
if (next instanceof HTMLElement) {
next.setAttribute('tabindex', '-1');
next.focus();
}
alert.remove();
});
</script>| Prop | Type | Default | Description |
|---|---|---|---|
title | string | - | Heading text for the card. |
childrenrequired | ReactNode | - | Content rendered inside the component. |
dismissLabel | string | 'Dismiss' | Accessible name for the dismiss button. |
onDismiss | () => void | - | Fired when the user dismisses the notification. |
className | string | - | Additional classes merged onto the root element. |
Dismissal is a focus problem first: the close button removes itself, and the browser's fallback is to drop focus on <body>, stranding keyboard users at the top of the page. Move focus to a stable neighbour before unmounting. Give the button a name that says what it closes - a dozen buttons called "Dismiss" are indistinguishable in a screen reader's element list. If the alert must stay gone across navigations, persist that server-side; local state alone means it returns on the next load.