交互设计(Interaction Design)
交互设计定义用户动作如何触发系统状态变化、界面怎样反馈、哪些操作被允许,以及错误和不确定状态如何恢复。
[!info] related notes
- 所属 MOC: ui-ux-moc
- 前置概念:
- 并列概念:
- 易混淆概念:
- 关系笔记:
交互设计(Interaction Design)
一句话定义
交互设计(Interaction Design)关注的是:
用户做了一个动作以后,系统应该怎样变化、怎样反馈、允许用户接着做什么,以及发生错误时怎样恢复。
最短模型:
User Action
↓
System State Change
↓
Feedback
↓
Next Available Action
UI 决定一个按钮长什么样,交互设计决定这个按钮什么时候可点、点下以后发生什么、多久得到反馈、失败后怎么办。
为什么“能点击”不等于设计完成
例如一个 Save 按钮:
[ Save ]
真正需要设计的是:
idle
↓ click
submitting
├─ success → saved
└─ failure → error → retry
还要继续问:
- 提交中还能不能重复点击?
- 成功反馈显示在哪里?
- 失败以后用户输入是否保留?
- 网络很慢时是否允许取消?
- 键盘 Focus 是否可见?
- 屏幕阅读器是否能理解状态变化?
这才是完整交互,而不是给按钮加一个 hover。
交互设计的核心问题
1. Affordance:看起来能不能理解怎么用
一个元素应该尽可能让用户从外观、位置和惯例中理解它的操作方式。
例如身体地图上的一个区域标记如果:
- 有 hover / focus;
- 鼠标形态变化;
- 当前选择有明显状态;
用户更容易理解它是可交互入口。
如果一个普通文本突然可以点击,却没有任何可供性提示,就需要用户“试一下才知道”。
2. Feedback:每个关键动作都要有反馈
用户操作以后,需要知道系统有没有收到动作。
例如:
点击身体区域
→ 立即高亮区域
→ 详情区域进入 loading / 切换状态
→ 数据完成后显示内容
而不是点击后几百毫秒什么都没发生,让用户再次点击。
反馈可以来自:
- pressed / selected state;
- loading;
- toast;
- inline message;
- progress;
- animation;
- 内容本身的变化。
反馈不是越多越好,要选择最接近操作上下文的位置。
3. Visibility:系统状态必须对用户可见
尤其是异步和 Agent 产品:
已收到
正在处理
正在检索
等待确认
已完成
失败,可重试
用户不需要看到模型内部的私有推理,但应该知道现在发生了什么、是否需要自己行动。
4. User Control:用户要有控制权
一个成熟交互通常会提供恰当的:
- cancel;
- back;
- undo;
- edit;
- retry;
- stop;
- reject;
- confirm。
特别是 AI / Agent 场景,不能因为系统“自动化”就把所有控制权拿走。
5. Constraint:用约束减少错误
好的交互会限制不合理操作。
例如:
- 数据正在提交时避免重复提交;
- 必填项未完成时明确指出;
- 不确定身体区域时要求确认;
- 高风险动作需要额外确认;
- 当前权限不足时不要展示一个看似可执行却必然失败的路径。
6. Consistency:相同事情应该有相同交互
如果:
- 一个区域点击后右侧展开;
- 另一个区域点击却跳整页;
- 相同 Delete 在不同页面行为不同;
用户就需要重新学习。
一致性不仅是组件样式一致,还包括行为一致。
7. Timing:反馈的时机也是设计
例如:
- 用户点击后应立即出现本地反馈;
- 后端结果稍后到达;
- 长任务要持续提供进展;
- 过快闪过的 loading 反而可能造成视觉抖动。
交互设计关心“什么时候发生”,而不只是“发生什么”。
状态设计是交互设计的一部分
一个真实组件通常至少可能有:
idle
hover
focus
active
selected
loading
success
empty
partial
disabled
error
offline
但这些状态不是为了列清单,而是为了回答:
当前用户能理解什么?可以做什么?下一步如何到达?
请求层的 loading、空态、失败、超时和重复提交已经有专门的 前端交互状态统一处理,不需要在每个页面重新发明。
CSS 层面的 hover / focus / active 细节可继续参考 伪类状态设计。
BodySense:区域选择的完整交互
假设用户点击人体图上的左肩。
不完整设计
点击左肩
→ 打开详情
更完整的交互规格
Trigger:
用户点击或键盘激活左肩区域。
Immediate Feedback:
左肩进入 selected 状态;其他区域取消 selected。
State Change:
selectedRegion = leftShoulder
Async State:
如果详情未缓存,详情区域进入局部 loading;人体地图保持可见。
Success:
展示左肩摘要与相关记录。
Failure:
详情区域显示错误和 Retry;不清空整个人体地图。
Next Actions:
切换其他区域 / 查看详情 / 更正记录 / 继续咨询。
Accessibility:
区域可由键盘聚焦和激活;selected 状态不能只依赖颜色表达。
这就是前端工程里真正可实施的 Interaction Spec。
BodySense:AI 正在更新身体记录
当对话中的信息正在被 AI 转成结构化身体记录时,不应该让界面突然“神奇地变了”。
可以有这样的状态:
用户补充:左肩抬高手臂时疼
↓
消息已发送
↓
AI 正在响应
↓
系统识别出可能与左肩记录相关
↓
如果区域明确 → 更新记录
如果区域不明确 → 请求确认
↓
地图区域状态变化
用户真正需要看见的是:
- 系统正在处理;
- 哪个事实被更新;
- 需要自己确认时明确出现动作。
不需要展示模型完整内部思考过程。
Confirmation、Undo 与高风险动作
不是所有动作都需要 Confirm Dialog。
可以按成本判断:
低成本、容易撤销
→ 直接执行 + Undo
中等成本
→ 清晰反馈 + 必要时 Undo
高成本、不可逆或涉及安全
→ 执行前确认
过度 Confirmation 会形成“用户无脑点确定”的习惯,反而降低安全性。
BodySense 中,普通区域切换当然不需要确认;但涉及重要健康风险提示、覆盖用户明确确认过的信息等行为,则应该更谨慎设计。
Empty State 也是交互状态
Empty State 不是装饰插画,而是用户进入一个“正常但没有内容”的状态。
它应该回答:
现在是什么状态?
为什么这里是空的?
下一步能做什么?
例如:
暂时没有身体记录。完成一次对话后,相关区域会显示在这里。
当数据出现以后,这段引导就应该退出界面,而不是继续占据注意力。
Motion 的职责
动效的价值主要是:
- Orientation:告诉用户东西从哪里来、去了哪里;
- Feedback:表示操作被接收;
- Continuity:保持两个状态之间的空间连续性;
- Attention:适度引导重要变化。
例如 Drawer 从右侧进入,会帮助用户理解它仍然属于当前页面的二级上下文,而不是跳到了另一个完全无关的地方。
动效不应该只是“看起来高级”。
实战写 Interaction Spec 的模板
对每个关键动作都可以写:
Trigger:
什么触发?click / keyboard / submit / agent event ...
Precondition:
什么条件下允许?
Immediate Feedback:
动作发生后立即显示什么?
State Transition:
从什么状态到什么状态?
Async / Long-running:
等待期间怎样表现?是否可取消?
Success:
完成后怎样反馈?
Failure:
失败在哪里展示?
Recovery:
用户怎样重试、撤销或返回?
Next Actions:
完成后还能做什么?
Accessibility:
键盘、Focus、语义和非颜色提示是否成立?
这套模板可以直接放进功能设计文档或交给 AI coding agent 作为实现约束。
交互设计 Review
开发完成以后,不只看截图,可以实际操作并问:
- 每次点击都有立即反馈吗?
- 用户是否知道当前处于什么状态?
- Loading 时还能不能做不该做的事情?
- Error 是不是只有 Toast,却没有恢复路径?
- 用户能否撤销、停止、返回或纠正?
- 相同交互在不同模块是否一致?
- Hover、Focus、Selected、Disabled 是否完整?
- 是否存在“看起来能点但不能点”或相反的元素?
- 动效是否帮助理解,而不是制造延迟?
- 键盘操作和屏幕阅读器是否仍然成立?
最短记忆
Flow 决定用户走哪条路;Interaction 决定路上的每一步怎样发生;State 决定系统此刻是什么;UI 把这些变化表达出来。