默认状态只出现一次,其他状态每天都会被看到。
一、一个下午,三次「页面坏了」
以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。
郁川的客户反馈系统上线第一周,他收到三条几乎一样的反馈:「页面坏了。」
第一条:新注册用户打开工单列表,看到一片空白,以为加载失败。其实是空状态,只是什么都没有写。
第二条:保存一条反馈后,页面没有变化,用户又点了三次,产生三条重复记录。保存是成功的,只是没有成功提示。
第三条:团队成员打开设置页,看到一行红色英文 403 Forbidden。他没有权限,但页面没有告诉他该找谁。
三个问题都不是功能缺陷,而是状态缺失。郁川写页面时只设计了「有数据、能保存、有权限」这一条路径,而用户实际走进的是另外几条。
一个页面至少有七种状态:默认、空、加载、错误、成功、无权限、离线。默认态只在条件齐备时出现一次,其余状态才是日常。
状态容易被跳过,是因为开发时总在「数据齐备、权限完整、网络正常」的条件下调试。这个条件在真实使用中很少成立:新用户没有数据,普通成员没有权限,移动网络随时会断。
状态缺失不会报错,只会被当成 bug。 它不在测试用例里,不会触发告警,最后以「页面打不开」的形式出现在客服对话中。
二、六态矩阵
把每个页面的状态列成矩阵,缺哪一格一眼就能看出来。
| 状态 | 触发条件 | 必备元素 | 常见缺陷 |
|---|---|---|---|
| 默认 | 有数据、有权限、网络正常 | 内容 + 主操作 | 无 |
| 空 | 无数据 | 一句解释 + 一个创建入口 + 示例 | 只有空白或只写「暂无数据」 |
| 加载 | 请求进行中 | 骨架屏或进度提示 | 白屏、无超时、无限转圈 |
| 错误 | 请求失败或校验不通过 | 发生了什么 + 为什么 + 下一步 | 只显示错误码 |
| 成功 | 操作完成 | 明确反馈 + 后续动作 | 静默成功、无确认 |
| 无权限 | 角色不足或未订阅 | 说明原因 + 升级或申请入口 | 裸露 403 |
| 离线 | 网络不可用 | 状态说明 + 重试 + 本地草稿 | 操作丢失 |
空状态要给出下一步。 「暂无数据」是描述,不是设计。有效空状态包含三样:为什么这里是空的、现在可以做什么、做完会看到什么。
空状态与筛选无结果不是一回事。 前者是「还没有内容」,后者是「有内容但被筛掉了」。两者的文案与入口完全不同:前者引导创建,后者引导清除筛选。用同一句「暂无数据」会同时误导两种用户。
成功状态要敢于打扰。 保存、发送、支付这类动作必须有可见反馈。提示可以轻(一行 toast),但不能没有。静默成功会让用户重复操作。
提示位置要跟着动作走。 局部操作(保存一行)用行内提示,全局操作(导出全部)用页面级提示。所有反馈都堆在右上角,用户会错过与自己相关的那一条。
状态之间要有优先级。 同时断网又无权限时,先告诉用户网络问题,因为那是他能自己解决的。把两个错误一起显示,用户不知道该先处理哪个。
错误状态要区分「可重试」与「不可重试」。 网络超时可以给重试按钮;校验失败重试一百次也没用。把两者混在一个「操作失败」里,用户只能反复点击。
无权限状态要给出路径。 告诉用户缺什么权限、谁能给、怎么申请。裸露的状态码是把内部实现暴露给了用户。
离线状态要保住用户的输入。 表单填写到一半断网,最糟的处理是清空。至少保留本地草稿,并明确告知「已暂存,联网后可提交」。
三、加载的三个阈值
加载不是「转圈就行」,它有三个明确的时间阈值。
0–100ms 无需提示,用户感知为即时
100ms–1s 轻微提示(按钮 loading、局部骨架)
1s–10s 必须显示进度或骨架屏,并说明在做什么
>10s 需要可取消、后台继续或分阶段反馈
超过 10s 无反馈,用户会认为页面卡死
骨架屏优于转圈。 转圈只说明「在等」,骨架屏还说明了「等来的是什么形状」,能降低感知等待时间。
短请求不要加提示。 100 毫秒内完成的请求加一个 loading 图标,反而会让界面闪烁,比不加更糟。判断标准是实测耗时,不是感觉。
乐观更新要能回滚。 点赞、勾选这类操作可以先更新界面再发请求,但失败时必须回到原状态并给出提示,否则用户会以为改动已保存。
超过一秒的操作要给按钮状态。 点击后按钮立即进入 loading 并禁用,是防止重复提交最便宜的手段。
长任务要可取消。 导出、批量处理这类操作,给一个取消入口,比显示一个精确但走得很慢的进度条更让人安心。
加载失败要有超时。 没有超时的请求会永远转圈。设一个上限(例如 15 秒),到点转为错误态并给重试。
长任务要给阶段反馈。 「正在处理 2/5」比一个不确定的进度条更让人愿意等。阶段可以粗,但必须真实,不要用假进度。
四、错误与无权限怎么写
错误状态的设计,一半在视觉,一半在文案。
错误信息要回答三个问题。 发生了什么(保存失败)、为什么(文件超过 10MB)、下一步(压缩后重试或换一个文件)。只写「操作失败」等于没说。
内部错误码要有一张映射表。 把常见的十来个错误码各自对应一句用户语言,集中维护。临时在页面里拼字符串,会出现同一个错误在不同页面有三种说法。
错误要出现在出错的位置。 表单校验错误标在对应字段旁,不要全部堆在页面顶部。用户需要知道改哪里。
不要用红色表达一切。 红色表示阻断性错误。警告用黄色,提示用中性色。全部标红会让真正的错误失去权重。
颜色之外还要有形状。 错误用图标加文字,成功用对勾加文字。只靠颜色区分,在灰度打印与色觉障碍场景下会完全失效。
无权限页要说人话。 「你需要管理员权限才能查看账单。请联系工作区管理员,或在设置中升级套餐。」比 403 Forbidden 有用得多,也顺带完成了一次转化引导。
错误页要保留退路。 至少给一个「返回」或「回到首页」。用户走进死胡同后,只能关掉标签页。
五、行动清单与复算验收
- 列出产品里所有主要页面,为每个页面画出状态矩阵
- 标出尚未设计的状态,优先补空、错误、无权限三类
- 为每个空状态写一句解释、一个创建入口、一个示例
- 检查所有保存类操作,确认有可见成功反馈
- 给所有请求加超时,超时后转为错误态并提供重试
- 把状态码页面替换为带原因与下一步的说明页
- 检查离线场景下表单输入是否保留
- 统计状态覆盖率,记录本月补了哪几格
验收标准:能报出主要页面的状态覆盖率,并指出仍然缺失的状态。 只回答「都处理了」的,说明矩阵没画过。
状态覆盖率 = 已设计的状态数 ÷ 应有状态数
按页面计算,再取平均
低于 70%:用户会遇到「页面坏了」的体验
使用边界与实操验收
本文讲状态矩阵与状态设计,不涉及空状态如何承担激活功能,那属于空状态与示例数据:60 秒内看到成品 ;状态里的具体文案写法属于第 07 篇;上线前的一致性检查属于第 09 篇;首屏的信息层级属于第 05 篇。
本文也不主张「每个状态都要独立页面」。局部状态(某个列表加载中)用局部提示即可,只有整页不可用时才需要整页状态。
验证以覆盖率为准:任选三个主要页面,现场断网、清空数据、用低权限账号登录,各走一遍。三次里有一次出现白屏或裸露错误码,就说明状态还没设计完。
另一个容易忽略的验收点:把所有状态截图排在一起,看它们是否属于同一个产品。空状态用插画、错误状态用系统弹窗、加载状态用另一个框架的 spinner,这种拼装感比缺少状态更伤信任。
状态也该写进文档,哪怕只有一页。每个页面有哪几态、每态显示什么、由谁触发,写清楚之后,新增页面时才有可参照的模板。
关键参考与核验范围
本文的时间阈值与比例为教学演示。核验日期:2026-10-24。
- Nielsen Norman Group: Response Times: The 3 Important Limits :100ms、1s、10s 三个响应阈值的来源与适用条件。
- WCAG 2.1: Focus Visible :键盘操作下焦点状态必须可见的要求,属于状态设计的一部分。
上述两条只用于说明公开研究与规范,不构成对任何提示组件或框架的推荐。具体超时时间应按业务与网络条件调整。
系列导航
- 上一篇:首屏与信息架构:一页只回答一个问题
- 下一篇:微文案:按钮、报错与空状态怎么说
- 回到目录:一个人把产品做得像样:品牌、视觉识别与设计系统
- 相关阅读:空状态与示例数据:60 秒内看到成品 、设计验收:一致性、可访问性与跨平台的一张表
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。