Success state
CSS-only success indicators with animated checkmarks, oklch() colors, and accessible focus states.
Form submitted
Your changes have been saved
Task completed
Great job! All items checked off
Quick implementation
/* HTML: <div class="success-item" role="status">
<div class="success-icon"></div>
<div class="success-content">
<h4>Success title</h4>
<p>Success message</p>
</div>
</div> */
.success-icon {
width: 1.5rem;
height: 1.5rem;
border-radius: 50%;
background: oklch(0.72 0.14 155);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
/* Animated checkmark using ::after */
.success-icon::after {
content: "";
width: 0.35rem;
height: 0.7rem;
border: 2px solid white;
border-top: none;
border-left: none;
transform: rotate(45deg) translate(0, 0);
opacity: 0;
animation: checkmark 0.25s ease-out forwards;
animation-delay: 0.1s;
}
@keyframes checkmark {
to {
transform: rotate(45deg) translate(0, 0);
opacity: 1;
}
}
/* Accessible focus state */
.success-item:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
.success-icon::after {
animation: none;
opacity: 1;
}
}
Prompt this to your LLM
Crafted prompt — includes role, intent, constraints, framework variant, and edge cases.
You are a senior frontend engineer specializing in accessible UI components.
Goal: Create a success state indicator with an animated checkmark — no JavaScript for the animation.
Technical constraints:
- Use CSS animation on a ::after pseudo-element to draw the checkmark stroke.
- Use oklch() for all colors (success green: oklch(0.72 0.14 155), white border).
- The checkmark should animate in with opacity and transform on load or when the parent becomes visible.
- Include a focus-visible state for keyboard accessibility on interactive success items.
- Respects @media (prefers-reduced-motion: reduce) by disabling the animation.
Framework variant (pick one):
A) Vanilla HTML/CSS only — return a .success-item wrapper with .success-icon and .success-content classes.
B) React component — accept `title`, `message`, `onClose` props; return the structure with proper ARIA roles.
Edge cases to handle:
- Screen reader announcement: use role="status" and aria-live="polite" on the container for dynamic success messages.
- What if the animation is too fast for some users? Provide a reduced-motion fallback.
- Color contrast: ensure the white checkmark on the green background passes WCAG AA.
Return the HTML structure and CSS, clearly separated.
Why this matters in 2026
Success states are everywhere — form submissions, task completions, file uploads. The old pattern was to reach for JavaScript animations or SVG libraries for checkmarks. Now, a simple CSS pseudo-element with animation and oklch() colors delivers the same polish without the overhead. It's also easier to theme: swap the green value and the entire design system updates.
Plus, it's keyboard accessible out of the box. Add tabindex="0" and focus-visible styles, and you're WCAG compliant.
The logic
The checkmark: A ::after pseudo-element draws a 2-pixel border on the right and bottom edges, rotated 45 degrees to form the L-shape. Starting with opacity: 0 and a slight translate offset, the animation brings it to opacity: 1 for that "strokes in" effect.
oklch() for success green: oklch(0.72 0.14 155) is a perceptually uniform green that looks consistent across light and dark modes. No need for separate --success-color tokens per theme.
Reduced motion: The @media (prefers-reduced-motion: reduce) query disables the animation and shows the checkmark immediately — essential for users who experience motion sickness.
Accessibility & performance
For dynamic success messages (e.g., after form submission), use role="status" and aria-live="polite" so screen readers announce the update. Interactive items (like clickable success toasts) need tabindex="0" and visible focus rings.
Performance-wise, the animation only touches opacity and transform — both GPU-accelerated properties that don't trigger layout recalculations. On low-end devices, the reduced-motion fallback ensures instant rendering without animation overhead.