卡片、列表与筛选:保住上下文
筛选、排序和拖拽会同时改变内容与位置。好的连续性让视线跟得上变化,也让操作结果更可信。
卡片、列表和筛选里的变化经常同时发生:项目进入、离开、重排、刷新和收缩。用户需要一条能追踪的因果链,知道自己操作的是谁、它去了哪里,以及为什么周围内容也随之变化。
先确认用户需要追踪的是单个对象、列表顺序,还是筛选后的整体结果。
实施路径
- 01
保留可辨认的锚点
让被操作的卡片保留身份和位置线索,避免突然消失后让人重新找。
- 02
顺序变化分批发生
列表更新用短间隔建立阅读顺序,数量多时控制总时长。
- 03
筛选结果给出解释
结果收缩时保留筛选条件和命中数量,让变化有原因可循。
先让用户认得出同一个对象
连续性的起点是对象身份。一个卡片被选择、拖拽或筛选后,它的标题、缩略图、边界和相对位置应该尽量延续。即使尺寸要变化,也要让关键识别线索留在画面里。比如任务卡从看板进入详情页时,标题和主色块可以在新布局中继续出现;筛选后只剩三条结果时,保留激活的筛选条件和数量,用户便能把收缩后的列表与刚才的选择联系起来。
身份线索也能帮助处理内容更新。来自实时协作、轮询刷新或后台同步的新项目,不要和用户刚操作的项目混成一团。新项目可以从列表边缘轻量进入,并用短暂的“新增”标记说明来源;被更新的项目可以只变化相关字段,避免整张卡片反复闪动。用户会把每一次变化归因到自己的动作、别人的动作或系统刷新,界面提供的线索越清楚,认知负担越低。
进入、移动和离开共用一条时间线
列表变化很容易显得乱,因为进入、离开和位置移动同时发生。处理的关键在于给它们一个共同的节奏。先让要离开的项目降低存在感,再让保留项目平移到新位置,最后让新增项目出现。它们并不需要逐帧串行,只要开始和结束有清楚的先后关系即可。对于十条以内的列表,120–220ms 往往能完成一次干净的重排;项目更多时,优先缩短单项延迟,避免最后一个项目很久以后才落位。
视觉上的移动应当真实反映数据变化。排序后卡片最好沿着它们实际要去的位置移动;如果采用 crossfade,保留旧位置和新位置的重叠时间,让眼睛有机会建立对应关系。列表容器本身保持稳定高度也很重要。大面积的高度跳动会让用户以为页面重新加载了,而非理解为内容发生了筛选。对小屏幕来说,连续性还意味着滚动位置可控:用户刚刚触碰的区域应尽可能留在视口附近。
筛选要保留条件、数量和空状态
筛选的动效承担解释责任。用户选择“已完成”或输入关键词后,列表会减少、排序会变化、统计数字也会更新。激活的筛选 chip、搜索词和结果数量应该先于或同时于列表变化出现,这样用户先知道规则,再看到结果。若只让卡片瞬间消失,页面会像发生了故障;若条件、数量和卡片同步更新,用户能理解这是一次受控的收缩。
空状态同样属于连续性。零结果也是列表的一种结果,它应接住刚才的筛选条件:显示“没有匹配‘预算’的项目”,提供清除筛选或换一个条件的入口。空状态进入时,一次淡入加上稳定的占位就足够。若筛选结果很快来回变化,避免每次都播放完整出入场;在输入框连续输入时,可以用更短的过渡,等用户停止输入后再让最终结果稳定下来。
刷新、排序和拖拽各自有不同信号
三种变化看起来都在移动卡片,实际含义完全不同。刷新告诉用户系统得到了新数据;排序表达一个新的比较规则;拖拽确认用户亲手改变了顺序。刷新适合轻量提示和局部更新,排序适合展示当前排序规则与整体重排,拖拽则需要拾取态、占位和落点。把它们做成同一种“卡片飞来飞去”,会让用户失去对原因的判断。
实现时可以把“变化来源”作为状态的一部分。列表容器记录当前是 filter、sort、refresh 还是 drag;每种状态只触发自己需要的视觉规则。这样也利于测试:筛选时检查结果数量和焦点,排序时检查对象的最终顺序,拖拽时检查键盘与触屏路径。动效不再是覆盖在数据之上的装饰层,它成为状态变化的可见输出,和业务逻辑一起被验收。
把连续性写进列表组件的验收
列表组件可以把连续性写成一组明确规则:对象身份如何保留、容器高度在何种条件下变化、筛选条件和数量何时更新、移动距离和总时长的上限是多少、空状态承接哪些动作。这样新页面引用组件时,不会每次重新猜测动画该怎么做。设计评审关注的是用户是否能追踪,工程评审关注的是最终数据顺序和焦点,两个角度围绕的是同一份契约。
验收时要用真实规模的数据。三张卡片的漂亮位移,放到五十条搜索结果上可能变成拖延。测试一次连续输入、一次多条件筛选、一次排序和一次移动端滚动中的更新;同时开启减少动效偏好,确认规则、数量和焦点仍然清楚。好的连续性并不要求每个对象都演一段完整动画,它要求每次变化都有来处、有结果、有可以继续操作的空间。
列表连续性验收清单
- 被操作对象保留可辨认线索标题、缩略图、色块或相对位置在新状态中继续出现。
- 筛选规则和结果数量同步可见先让人知道规则,再让列表收缩或重排。
- 离开、移动和进入共享短节奏项目多时控制总时长,避免延迟排队。
- 空状态解释条件并给出下一步保留搜索词或筛选条件,并提供清除或替换入口。
- 刷新、排序与拖拽可被区分每种来源使用自己的状态与验收路径。
案例:项目筛选先更新数量,再收缩卡片
筛选条件和命中数量放在列表上方,保留项平移,离开项只降低透明度。
.result-list { display: grid; gap: 12px; }
.result-card { transition: transform 180ms ease-out, opacity 140ms ease-out; }
.result-card[data-visibility="leaving"] { opacity: 0; transform: scale(.985); pointer-events: none; }
.result-meta[data-updating="true"] { color: var(--motion-ink); }
.result-empty { min-height: 160px; opacity: 0; visibility: hidden; transition: opacity 140ms ease-out; }
.result-list[data-empty="true"] + .result-empty { opacity: 1; visibility: visible; }
@media (prefers-reduced-motion: reduce) { .result-card, .result-empty { transition-duration: 1ms; } }离开项目不使用大位移,保留项目的真实位置移动更容易被看清。命中数量通过 data-updating 先变化,建立“规则已经生效”的线索;空状态预留高度,列表收缩后页面不会突然塌陷。