notifications-and-recovery
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNotifications 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 | 用户操作的临时结果(已保存、已发送、已删除) | 4-6秒自动关闭,支持手动关闭 |
| 内联错误提示 | 字段级验证、表单错误 | 修正后自动清除 |
| 警告横幅 | 影响当前上下文的持续性问题 | 手动关闭或问题解决后自动消失 |
| Modal / dialog(模态框/对话框) | 需要用户做出决策才能继续的阻塞性错误 | 必须用户操作后才能关闭 |
| 空状态 | 暂无数据——引导用户完成首个操作 | 不适用 |
| 骨架屏/加载状态 | 异步内容待加载 | 加载完成后被内容替换 |
| 就地确认 | 就地编辑已保存、行已更新、项目已切换 | 2-3秒后自动清除 |
Toast Notifications
Toast通知
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 dismissedNever: multiple simultaneous toasts. Queue them; show one at a time.
Toast用于确认后台操作已完成,弹出时不会打断用户的操作流程。
放置位置: 底部居中或底部右侧。切勿放在顶部居中——会与页面内容和导航区域冲突。
显示时长: 信息类提示显示4-6秒。错误提示需保持显示直到用户关闭——用户需要时间阅读并采取行动。
结构:
[图标] 提示文本 [操作按钮] [×]- 图标:颜色编码(绿色✓表示成功,红色✗表示错误,橙色⚠表示警告,蓝色ℹ表示信息)
- 提示文本:一句话,使用通俗易懂的语言
- 操作按钮(可选):最多一个操作,如“撤销”“重试”“查看”
- 关闭按钮:错误提示必须保留;成功提示可选择保留
✓ "更改已保存。"
✓ "消息已发送。 [撤销]"
✗ "无法保存,请检查网络连接。 [重试]" ← 保持显示直到用户关闭注意: 切勿同时显示多个Toast。应将它们排入队列,一次只显示一个。
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 for screen readers
aria-describedby
html
<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
内联错误提示出现在触发错误的元素附近,是上下文关联性最强、最具可操作性的错误反馈形式。
表单验证:
- 在用户离开字段时(失焦)验证,而非每次按键时——按键验证过于频繁,会造成干扰
- 提交表单时进行完整验证
- 在字段正下方显示红色错误提示文本,并搭配图标
- 字段边框改为
--color-error - 使用关联错误提示与对应字段,供屏幕阅读器识别
aria-describedby
html
<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>就地编辑:
- 当字段进行就地编辑(表格单元格、卡片标题)时,在字段附近显示保存/取消控件
- 保存成功:显示短暂的成功标识(“✓ 已保存”),2秒后自动消失——不要跳转页面
- 保存失败:在字段下方显示内联错误提示,并提供重试选项
- 取消编辑:立即恢复原始值
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)
横幅会持续显示,直到问题解决或用户手动关闭。
适用场景:
- 服务降级(“部分功能暂时无法使用”)
- 需要用户处理的账户问题(“您的订阅将于3天后到期。[续费]”)
- 持续同步错误(“更改无法保存。[重试]”)
- 与当前页面相关的重要公告
放置位置: 受影响区域的顶部,除非问题是全局的,否则不要放在整个页面顶部。
结构:
[图标] [提示文本——描述问题及其影响范围] [操作按钮] [×]- 每个区域一次只显示一个横幅——同时显示多个横幅会引发用户的焦虑感
- 除非问题具有阻塞性,否则应支持关闭
- 颜色遵循状态配色规范:红色(错误)、橙色(警告)、蓝色(信息)、绿色(成功/已解决)
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
适用于临时故障(网络问题、超时、速率限制):
“无法加载结果。”
[重试]- 重试按钮触发相同操作
- 连续3次重试失败后,升级提示:“仍有问题?[联系支持]”
- 重试过程中显示加载动画——避免用户重复点击
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
适用于破坏性或不可逆操作(删除、归档、发送):
“消息已发送。 [撤销] ×”- 撤销窗口:5-10秒。Toast在此期间持续显示
- 窗口关闭后,操作即生效
- 对于低风险操作,撤销比确认对话框更优——更快且更少干扰
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]"
适用于长文本输入(表单、文档、编辑器):
- 每30-60秒静默自动保存
- 保存失败时提示:“自动保存失败——您的更改已存储在本地。[重试保存]”
- 崩溃或关闭后重新打开时提示:“您有[时间]的未保存更改。[恢复] [丢弃]”
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.
加载状态不属于错误,但仍需进行设计。
- 骨架屏:适用于内容密集型页面——加载数据时显示内容布局轮廓
- 加载动画(Spinner):适用于针对性的异步操作(按钮加载、内联刷新)
- 进度条:适用于已知时长的长操作(文件上传、多步处理)
- 加载时切勿显示空白页面——始终展示一些内容
与加载动画相比,骨架屏能减少用户感知的等待时间。骨架屏的形状应与实际内容布局匹配。
The Notification Center
通知中心
Toasts and banners are transient; a notification center is the persistent place a user goes to review and control what reaches them. Two things make it work.
Easy to reach, and easy to control. The user must get to their notification preferences with almost no digging (a bell icon → the center → settings). And keep the control model coarse — 1 to 3 categories at most, each with a simple level:
- — none of this category
Off (0) - — only the important ones
Minimal - — everything
All / granular
Don't build a wall of per-event toggles. Two real needs dominate: silence everything, or keep one or two categories. Design straight for those — a prominent "mute all" / "mark all read" plus 1–3 category switches.
Minimise reading. The center is scanned, not read. Group by category, lead each item with a recognisable icon and the entity/action (not a paragraph), show unread state clearly, and let the whole list be cleared in one action. Reading is time (see [[ui-density]]) — a notification center that demands careful reading defeats its purpose.
Toast和横幅是临时的;通知中心是用户查看和管理通知的持久化入口。以下两点是其有效运行的关键。
易于访问,易于管理。 用户无需过多操作即可进入通知偏好设置(铃铛图标 → 通知中心 → 设置)。并且控制模型要简洁——最多1-3个分类,每个分类提供简单的选项:
- —— 关闭该分类所有通知
Off (0) - —— 仅接收重要通知
Minimal - —— 接收所有通知
All / granular
不要构建大量的逐事件开关。用户的核心需求主要有两个:全部静音,或保留1-2个分类的通知。直接针对这些需求设计——突出显示“全部静音”/“标记为已读”按钮,加上1-3个分类开关。
减少阅读负担。 用户会快速浏览通知中心,而非仔细阅读。按分类分组,每条通知以可识别的图标和实体/操作为开头(而非段落),清晰标记未读状态,并支持一键清除所有通知。阅读需要时间(参考[[ui-density]])——需要用户仔细阅读的通知中心违背了其设计初衷。
Notification Accessibility
通知无障碍设计
- Errors use — announced immediately by screen readers
role="alert" - Status updates use — announced politely (after current speech)
role="status" - Toasts must be reachable by keyboard — do not use on the close button
pointer-events: none - Auto-dismissing toasts must have sufficient duration (users may need more time to read)
prefers-reduced-motion
html
<!-- 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>- 错误提示使用——屏幕阅读器会立即播报
role="alert" - 状态更新使用——礼貌播报(等待当前语音结束后)
role="status" - Toast必须支持键盘访问——不要对关闭按钮设置
pointer-events: none - 自动关闭的Toast必须有足够的显示时长(开启的用户可能需要更多阅读时间)
prefers-reduced-motion
html
<!-- 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 and status updates via
role="alert"?role="status"
- 每个错误是否都提供了恢复操作(重试、撤销、联系支持)?
- Toast是否在成功时自动关闭,在错误时保持显示?
- 是否从未同时显示多个Toast?
- 内联错误提示是否放在字段附近,而非表单顶部?
- 表单错误是否通过与对应输入框关联?
aria-describedby - 警告横幅是否显示在受影响区域顶部,而非总是全屏显示?
- 长文本输入是否支持自动保存或草稿恢复?
- 加载状态是否在内容区域使用骨架屏,在针对性操作中使用加载动画?
- 错误是否通过播报,状态更新是否通过
role="alert"播报?role="status"