← 首页 / ✦ UX 交互模式 · 那些有名字的交互细节 待审核 7 页

✦ UX 交互模式 · 那些有名字的交互细节

一个界面好不好用,常常不取决于功能列表,而取决于一批被反复打磨、各自有名字的交互细节: 点击后界面是立刻响应还是转圈等待;一处数据被改动后用户能否一眼找到; 误删之后能不能反悔;鼠标斜着滑向子菜单时菜单会不会半路消失。 这些模式大多诞生于具体产品的实战(Gmail 的撤销发送、37signals 的 Yellow Fade、Amazon 的 Mega Menu), 后来沉淀为通用词汇。本系列把其中 7 个挑出来,每个都做成可交互触发、并排对照「有 / 没有」的 demo。 正文中文,交互模式 / API 关键词保持英文。

一条主线: 这些模式服务于同一个目标——缩短「操作」与「反馈」之间用户能感知的间隙。 有的是提前给反馈(Optimistic UI),有的是事后留后路(Snackbar Undo), 有的是读懂指针的意图(Safe Triangle / Hover Intent / Fitts's Law), 有的是用连续的运动替代生硬的跳变(View Transitions)。 即时反馈:让等待「不被感知」 optimistic · 乐观更新

Optimistic UI:先更新界面,再等服务器

点赞、收藏、勾选待办——这些操作几乎总是成功。乐观更新的思路是:点击瞬间就把 UI 更新到「成功后的样子」,把真正的网络请求放到后台;万一失败再回滚并提示。对照「悲观更新」(点击后 disable + spinner,等响应才变),拖动延迟与失败开关,看两种策略在同一条时间线上的体感差异。

yellow-fade · 黄色淡出

Yellow Fade Technique:让「刚刚变化的地方」自己跳出来

异步更新一张列表后,用户的视线不知道该落在哪。37signals 的经典做法:把刚新增 / 改动的那一行瞬间染成黄色,再缓缓淡回——用一次短暂的高亮把注意力主动引导过去,而不需要用户自己找。对照关掉高亮的版本,体会「找得到」与「找不到」的差别,并看 transition 时长如何影响可察觉度。

snackbar · 撤销优先

Snackbar & Undo:用「可以反悔」替代「你确定吗」

删除一项,与其先弹一个 confirm 打断用户,不如直接执行,再从底部滑出一条带「撤销」的 Snackbar,几秒后自动消失(Gmail 撤销发送即此模式)。它把确认成本从「每次操作前」挪到「极少数想反悔时」。demo 含倒计时进度条、悬停暂停、多条排队,并和 confirm() 流程并排对照。

读懂指针:在用户开口前理解意图 safe-triangle · 安全三角形

Safe Triangle:斜着滑向子菜单,不要半路关掉它

多级菜单的经典痛点:鼠标从父项斜向移动到子菜单时,中途会滑过其他父项,天真实现会立刻切走、把子菜单关掉。Amazon Mega Menu 的解法:以光标当前位置和子菜单两角连成一个三角形容差区,只要指针还在三角内,就暂缓切换。开关对比两种实现,并把三角区域和鼠标轨迹画出来

hover-intent · 悬停意图

Hover Intent:区分「路过」与「真的想看」

mouseenter 一触即发的菜单,会在鼠标只是路过时频繁闪烁。Hover Intent 加一道判定:指针进入后停留超过阈值(或移动速度降下来)才真正触发,离开则带一点关闭延迟。拖动阈值滑块,用「快速划过」和「停下来」两种手势,对比一触即发与带意图判定的触发次数。

hit-target · 点击热区

Fitts's Law:目标越大越近,越快越准

费茨定律把「指到一个目标多难」量化为 ID = log ₂(D/W + 1):距离 D 越大、目标 W 越小,耗时越长、越易点偏。两个推论很实用:视觉可以小,但热区(hit target)要够大(用 padding / 伪元素撑开);屏幕四角是无限大的目标。demo 实测你的点击时间,并演示「视觉=热区」与「视觉小、热区大」的命中率差距。

连续性:用运动替代跳变 view-transition · 共享元素转场

View Transitions:让同一个元素在两个状态间「长」过去

从列表点进详情,如果界面硬切,用户需要重新定位「我点的是哪个」。共享元素转场给前后两个状态里的同一元素标记 view-transition-name,浏览器自动补出它位移 + 缩放的中间动画,把缩略图平滑长成大图。先讲同文档版(document.startViewTransition()、和硬切并排对照),再到跨文档(MPA)版:两页同源各加一行 @view-transition { navigation: auto },真实的页面跳转也能补间——内嵌双页站点现场演示,可切 crossfade 与圆形 clip-path 擦除,并讲 ::view-transition-* 伪元素树。

为什么这些细节值得单独命名? 因为它们解决的都不是「功能缺失」,而是感知问题: 同样的请求延迟,Optimistic UI 让它感觉是零;同样的一次删除,Snackbar 让它不再可怕; 同样一条 DOM 更新,Yellow Fade 让它被看见。把它们抽象成有名字的模式, 团队才能在 code review 里说「这里该上 optimistic / 加个 hover-intent」,而不必每次从头解释。

🔗 相关链接

📐 规范 / 文档

📎 模式出处 / 背景