Home / Snippets / UI Components /

Alert banner

Four semantic alert variants — info, success, warning, and error — built with CSS custom properties and oklch() colors. No JavaScript required.

Info
Your changes have been saved to draft.
Success
Account created successfully! Welcome aboard.
Warning
Your subscription expires in 3 days.
Error
Failed to submit form. Please check required fields.
Widely Supported
uino-js

Quick implementation

<!-- Markup Structure -->
<div class="alert alert-info">
  <span class="alert-icon">ℹ️</span>
  <div class="alert-content">
    <div class="alert-title">Info</div>
    <div class="alert-message">Your changes have been saved.</div>
  </div>
</div>

/* CSS Pattern */
.alert {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem;
  border-radius: var(--radius);
  border-left: 4px solid transparent;
  font-family: var(--font-display);
}

.alert-icon { flex-shrink: 0; }

.alert-title { font-weight: 700; font-size: 0.9rem; }
.alert-message { color: var(--muted); font-size: 0.9rem; }

/* Info Variant */
.alert-info {
  background-color: oklch(0.2 0.02 240);
  border-left-color: oklch(0.65 0.2 240);
  color: oklch(0.9 0.02 240);
}
.alert-info .alert-title { color: oklch(0.95 0.05 240); }
.alert-info .alert-message { color: oklch(0.75 0.02 240); }

/* Success Variant */
.alert-success {
  background-color: oklch(0.2 0.02 150);
  border-left-color: oklch(0.65 0.2 150);
  color: oklch(0.9 0.02 150);
}
.alert-success .alert-title { color: oklch(0.95 0.05 150); }
.alert-success .alert-message { color: oklch(0.75 0.02 150); }

/* Warning Variant */
.alert-warning {
  background-color: oklch(0.2 0.02 80);
  border-left-color: oklch(0.7 0.2 80);
  color: oklch(0.9 0.02 80);
}
.alert-warning .alert-title { color: oklch(0.95 0.05 80); }
.alert-warning .alert-message { color: oklch(0.75 0.02 80); }

/* Error Variant */
.alert-error {
  background-color: oklch(0.2 0.02 30);
  border-left-color: oklch(0.65 0.2 30);
  color: oklch(0.9 0.02 30);
}
.alert-error .alert-title { color: oklch(0.95 0.05 30); }
.alert-error .alert-message { color: oklch(0.75 0.02 30); }

Prompt this to your LLM

Includes role, constraints, and framework variants.

Role: UI component specialist.

Goal: Generate accessible semantic alert components in pure CSS.

Constraints:
1. Use CSS custom properties per variant (info, success, warning, error).
2. Use oklch() for all color values.
3. No JavaScript required for styling.
4. Ensure keyboard/screen reader accessible (focus-visible, contrast).
5. Dismiss button optional using :has() selector.

Framework Variants:
A) Vanilla CSS: Use modifier classes (.alert-info).
B) React: Use styled-components with theme props.

Edge Cases:
1. ARIA role="alert" for dynamically injected alerts.
2. Contrast ratio compliance for text on colored backgrounds.
3. Handling multiline text gracefully.

Why this matters in 2026

Static CSS alerts often replace heavy JavaScript toast libraries for persistent messages. The key advantage here is the use of oklch() to generate semantically consistent color palettes. By defining a specific hue for each alert type (e.g., blue for info, red for error) and then mathematically deriving the background and text colors from that same hue, we ensure perfect harmony. This eliminates the "muddy" look that often happens when mixing hex codes manually.

The logic

The logic relies on the "left border" technique to signal severity visually without cluttering the UI. We use a base .alert class for layout (flexbox) and spacing. The specific variants (.alert-info, etc.) override the background, border color, and text color. Because oklch() separates lightness from hue, we can easily create a "faint" background by lowering the lightness (L) and chroma (C) values while keeping the hue (H) constant.

Accessibility & performance

Performance is native and instant. For accessibility, it is crucial to distinguish between static and dynamic alerts. Static alerts (like this demo) are part of the DOM flow. However, if these alerts are injected dynamically (e.g., form validation errors), you must add role="alert" or aria-live="polite" to the container so screen readers announce them immediately. Ensure the contrast ratio between the text and the colored background meets WCAG AA standards (4.5:1).