notifications-and-recovery
Notifications and Recovery
When something changes — success, failure, or anything in between — the user must know. And when something goes wrong, they must always have a path forward. A notification without a recovery action is just an apology.
Pattern Selection
| Pattern | When to use | Dismissal |
|---|---|---|
| Toast | Transient result of a user action (saved, sent, deleted) | Auto-dismiss 4–6s, manual close |
| Inline error | Field-level validation, form errors | Clears on correction |
| Alert banner | Persistent issue affecting the current context | Manual dismiss or resolved state |
| Modal / dialog | Blocking error requiring a decision before continuing | User action required |
| Empty state | No data yet — guide the user to the first action | N/A |
| Skeleton / loading | Async content pending | Replaced by content |
| In-place confirmation | Inline edit saved, row updated, item toggled | Auto-clears after 2–3s |
Toast Notifications
Toasts confirm that a background action completed. They appear without interrupting the user's flow.
Placement: bottom-center or bottom-right. Never top-center — it competes with page content and navigation.
Duration: 4–6 seconds for information. Errors should persist until dismissed — the user needs time to read and act.
Anatomy:
[Icon] Message text [Action] [×]
- Icon: colour-coded (green ✓ success, red ✗ error, orange ⚠ warning, blue ℹ info)
- Message: one sentence, plain language
- Action (optional): "Undo", "Retry", "View" — one action maximum
- Close button: always present on errors; optional on success
✓ "Changes saved."
✓ "Message sent. [Undo]"
✗ "Could not save. Check your connection. [Retry]" ← persists until dismissed
Never: multiple simultaneous toasts. Queue them; show one at a time.
Inline Errors
Inline errors appear adjacent to the element that caused them. They are the most contextual and actionable form of error feedback.
Form validation:
- Validate on blur (leaving a field), not on every keystroke — keystroke validation is noisy
- Validate on submit for the complete form
- Show the error message directly below the field, in red, with an icon
- The field border changes to
--color-error - Error message is associated via
aria-describedbyfor screen readers
<label for="email">Email</label>
<input id="email" aria-describedby="email-error" aria-invalid="true">
<p id="email-error" role="alert">Enter a valid email address.</p>
In-place editing:
- When a field is edited inline (table cell, card title), show save/cancel controls adjacent to the field
- On save: brief success indicator ("✓ Saved") that fades after 2s — do not navigate away
- On error: inline error message below the field with a retry option
- On cancel: restore the original value immediately
Alert Banners
Banners are persistent — they stay until the condition is resolved or the user dismisses them.
Use for:
- Service degradation ("Some features are temporarily unavailable")
- Account issues requiring action ("Your subscription expires in 3 days. [Renew]")
- Ongoing sync errors ("Changes are not saving. [Retry]")
- Important announcements tied to the current page
Placement: top of the affected section, not the entire page unless the issue is truly global.
Anatomy:
[Icon] [Message — describes the issue and its scope] [Action] [×]
- One banner at a time per region — multiple simultaneous banners create alarm fatigue
- Dismissible unless the condition is blocking
- Colour follows status colour conventions: red (error), orange (warning), blue (info), green (success/resolved)
Recovery Patterns
Every error state must have a path forward. Design the recovery action at the same time as the error message.
Retry
For transient failures (network, timeout, rate limit):
"Could not load results."
[Try again]
- Retry button triggers the same action
- After 3 failed retries, escalate: "Still having trouble? [Contact support]"
- Show a spinner during retry — do not let the user click multiple times
Undo
For destructive or irreversible actions (delete, archive, send):
"Message sent. [Undo] ×"
- Undo window: 5–10 seconds. Toast persists for this duration.
- After the window closes, the action is final
- Undo is preferable to confirmation dialogs for low-stakes actions — it is faster and less disruptive
Autosave and Draft Recovery
For long-form inputs (forms, documents, editors):
- Autosave every 30–60 seconds silently
- On save failure: "Autosave failed — your changes are stored locally. [Retry save]"
- On return after crash or close: "You have unsaved changes from [time]. [Restore] [Discard]"
Graceful Degradation
When a feature fails but the rest of the product still works:
- Show an error state for the failed section only — do not blank the entire page
- Offer a fallback: "Could not load recommendations. [Browse all products →]"
- Log the error silently; surface only what the user needs to know
Loading and Skeleton States
Loading is not an error, but it is a state that needs design.
- Skeleton screens for content-heavy pages — show the layout shape while data loads
- Spinners for targeted async actions (button loading, inline refresh)
- Progress bars for long operations with known duration (file upload, multi-step processing)
- Never show a blank screen while loading — always show something
Skeleton screens reduce perceived wait time compared to spinners. Match the skeleton shape to the actual content layout.
Notification Accessibility
- Errors use
role="alert"— announced immediately by screen readers - Status updates use
role="status"— announced politely (after current speech) - Toasts must be reachable by keyboard — do not use
pointer-events: noneon the close button - Auto-dismissing toasts must have sufficient duration (
prefers-reduced-motionusers may need more time to read)
<!-- Error: immediate announcement -->
<div role="alert">Could not save. Check your connection.</div>
<!-- Status: polite announcement -->
<div role="status" aria-live="polite">Changes saved.</div>
Review Checklist
- Does every error have a recovery action (retry, undo, contact support)?
- Do toasts auto-dismiss for success but persist for errors?
- Is there never more than one toast visible at a time?
- Are inline errors placed adjacent to the field, not at the top of the form?
- Are form errors associated to their inputs via
aria-describedby? - Do alert banners appear at the top of the affected section, not always full-page?
- Is autosave or draft recovery available for long-form inputs?
- Do loading states use skeletons for content and spinners for targeted actions?
- Are errors announced via
role="alert"and status updates viarole="status"?
More from dembrandt/dembrandt-skills
nielsen-usability-heuristics
UI design and review should apply Nielsen's 10 Usability Heuristics — the foundational principles for evaluating and improving usability. Use when auditing an interface, designing interaction flows, writing error messages, or reviewing any UI for usability issues.
45form-design
Forms have three layers of guidance: helper text below the input explains what to enter, placeholder shows the expected format, and validation confirms correctness. Real-time validation for complex inputs. Submit enables only when the form is valid. Use when designing or reviewing any form, input field, or data entry UI.
44color-mode-and-theme
Choose light, dark, or combined color mode deliberately based on brand tone and user context. Offer a theme selector only when user control genuinely matters — enterprise tools, data-heavy UIs, or extended-use applications. Use when defining the base color palette, designing a design system, or deciding whether to build dark mode support.
43generate-ui-from-brand
Pipeline skill — turns a URL or DESIGN.md into a concrete UI structure with decisions already made. Extracts live design tokens, normalizes them into a semantic system, applies UX principles, and outputs an actionable UI spec. Use when building UI for an existing brand from scratch, auditing a design system, or refactoring visual inconsistency.
42scroll-areas
Scroll areas inside a layout should be avoided wherever possible. When unavoidable, allow only one scroll axis at a time and always keep the user in control. Use when designing layouts, data tables, panels, or any component that might introduce an inner scroll container.
42micro-interactions
Micro-interactions are small, purposeful animations and responses that reward the user and make the interface feel alive — an animated icon, a satisfying toggle, a subtle reveal. Borrowed from the natural world, they add delight without distraction. Use when designing interactive components, success states, toggles, loaders, or any moment worth celebrating.
42