惊!半年实践血泪史,3000 字深度好文,一个爱树的设计师手把手教你如何设计「树 」!
树形控件是种常见的设计模式,几乎与图形化用户界面同时诞生,通过结构化的组织方式逐级展示内容,让整体信息架构一目了然,非常适合以网页或桌面端为载体的 B 端产品和生产力工具,比如电脑文件管理系统。
使用场景
树形控件通常有以下 4 种表现形式:
树列表树导航树选择思维导图
可以把它们进一步总结为 2 个使用场景:
1. 查看为主,编辑为辅
2. 编辑为主,查看为辅
其中,树列表、思维导图在 2 个场景中都有应用,而树导航和树选择多以查看为主。不同的使用场景,在设计上会有不同取舍。
结合树形控件的使用场景,对其的操作也如此分类。显然,「查看为主」时,对查看类操作的体验要求更高,而「编辑为主」时则相反。
新增节点
以新增节点为例,不同场景下用户有不同的诉求:
- 查看为主:快速建出一个节点,以进行后续操作
- 编辑为主:快速搭建出整棵树的结构
查看为主
可以考虑鼠标悬停到节点出现相关操作。但此时较难预测的是用户到底是想增加一个子节点还是同级节点。一个完备的解法就是让用户选择。但实际业务中,此处可能还要选择节点类型,比如语雀要选择文档还是表格。所以「节点类型 x 层级选项」有可能导致选项过多。此时可以有两种处理方式:
只允许新增子节点, 提供节点类型的选择提供同级/子级的选择,将节点类型的选择/修改放在后续流程中
针对第一种方法,我们需要额外思考一个问题:新建的子节点应该放在第一位还是最后一位?
我的第一反应是第一位,因为它离操作区域最近,从操作到反馈都很自然,也避免目录发生大幅度滚动,所以在语雀目录中是这样设计的。但是实际也有很多用户反馈希望是最后一个子节点,类似于1,2,3…… 的顺序从老到新排列。我没有办法去验证如果真的是加为最后一个子节点,会不会又有另一波反馈声音。后来我发现思维导图新增子节点就是新增在末尾,以及绝大多数产品也是加在末尾,所以下次我大概会选择放在最后试试。或者索性选择上述第二种方法来避免这个问题。
此外,界面上还需要提供一种方式,允许用户创建最顶层的一级节点。当界面较大时,可以放置在顶部,让用户更易发现。
编辑为主
相较于上述方法,可以给出更明确直接的界面操作和添加位置示意或快捷键。
语雀在进行目录改版时,本想统一「阅读页面」和「编排目录页面」的交互方式——采用「查看为主」的添加方式,却忽略了两个页面的用户诉求不一样。此时这里其实还可以借鉴思维导图的创建方式,使用Enter/Tab 键快速添加节点。
修改节点属性
结合实际业务,节点可能有不同属性,比如名称、类型、状态、优先级等。「查看为主」时,修改操作使用不多,可以考虑放入「…」中。
而「编辑为主」时,除了单个节点修改属性方便,还需要考虑连续修改多个属性,甚至是批量修改。如下图,树列表可以支持连续修改属性节点。
如下图,思维导图可以通过多选然后在格式面板统一修改属性。
调整结构
树形控件最有价值的部分就是其所表达的层级关系,常用调整结构的操作总结如下:
- 拖拽调整:适用于小范围调整结构顺序
- 非拖拽调整:适用于需要跨屏调整结构顺序
无论采用那种方式,都遵循以下设计原则:
- 所见即所得
- 高效精准
拖拽调整
简单而言,设计上要解决以下问题:
1. 如何让用户知道可以拖拽?
增加意向符号改变光标样式
2. 如何让用户知道可以怎么拖拽到哪里?
可以在拖拽中采用「插入位置符号」暗示用户,通常是一条彩色线条。应尽可能增加「插入位置符号」出现的机率,减少用户的困惑。设计时可以考虑上下左右两个方向的拖拽运动分别可以触发什么结果。
比如按以下方式简单把拖拽规则分为 3 大类,
当然在「插入位置符号」尽可能多出现的同时,也要让其出现的位置符合用户预期且易理解。比如向左移动「非末尾子节点」,如果强行给以一个符合逻辑的响应,「插入位置符号」可能离当前光标很远,甚至在屏幕外,且放手后可能引起目录结构较大变化,那么不如选择此时拖拽无响应。
这里再介绍「把一个节点调整为另一个的子节点」的两种拖拽规则,分别适用于不同场景。
文件夹式:树的父节点只能是类似于「文件夹」这样的虚拟分组,可以采用文件夹式交互,因为它比较符合用户把子节点放入一个容器中的心智思维导图式:当树的父节点可能是一个真实存在的对象,可以采用思维导图式交互,因为用户比较难以想象:一篇文档叠到另一篇之上=成为它的子文档?
3. 如何让用户快速拖拽到目标位置?
当用户掌握了拖拽规则后,就需要帮助用户快速实现自己的调整目标。拖拽过程中注意以下几点:
- 被拖拽节点可以半透明显示,以尽量少遮挡树形控件,方便用户定位目标位置。
- 被拖拽节点的原始位置可以以较弱的视觉效果展示,提示用户节点从哪里被拖拽。
- 整棵树的结构不要发生变化,以免原先确定的目标位置发生位移。
- 结构层级较深时,通过辅助示意帮助用户确定会将节点拖拽到哪一层级。
- 如何让用户确定拖拽结果满足自己的期望?
当以上问题都解决后,这个也许就不成问题。当然也可以增加二次确认的微交互。
选中被拖拽对象增加临时性底色
非拖拽调整
调整结构也可以通过非拖拽的方式完成。拖拽是一种直观,但不轻松的操作,尤其是当树很庞大需跨屏拖拽时。此时可以增加按钮操作,直接指定目标位置,精确且快速。
当「编辑为主」时,调整结构也需要考虑批量操作。如下图,支持多选节点同时调整,被调整结构的节点有可能在原处于不同分支的不同等级,批量调整后会成为同一个字节的同级节点。
删除节点
不让用户疑惑:我的内容去哪儿了?
删除是个比较慎重的操作,所以此处应该询问用户是只删除本节点,还是本节点及其下所有节点。
如果只删除本节点,首先本节点需要从树形控件中消失,以代表删除成功,然后其子节点可以上移一级,保证用户不会误以为内容丢失。
缩放视图
查看时,思维导图可视化效果更好。针对思维导图,需要考虑视图的放大缩小,适应视口/真实大小切换。比如下图语雀思维导图的「缩放视图」功能(不过这个设计把回到中心和适应画布藏的有点深)。
折叠层级
当树形控件庞大时,需要能够快速折叠/展开层级,包括全部层级或者某一层级。如果是一棵「私人树」,记住用户折叠的展示层级,并且在下次进来时仍旧保持。如果是一棵「公开树」,可以增加默认展开设置,比如下图语雀中编排目录的操作。
值得注意的是,折叠层级和缩放视图的操作都应该提供快捷键,会比通过界面操作更加高效,也不会打断查看过程。可以想象一下你正在一个会议中展示一张思维导图,在界面上操作「缩放视图」耗费更多时间,也会在夺走走观众的注意力。
附上常见查看操作快捷键,仅供参考:
查看操作 | 快捷键 |
---|---|
折叠/展开子节点 | ctrl / |
实际大小 | ctrl 0 |
放大 | ctrl + |
缩小 | ctrl - |
缩放画布 | ctrl + 鼠标中键滚动 |
移动画布 | space + 鼠标拖拽 |
上述部分快捷键会和浏览器自带快捷键冲突,使用时需要覆盖浏览器快捷键。
搜索和筛选
当节点数量很多时,树形控件应该支持搜索查找节点,搜索关键词可以高亮显示;或按条件筛选展示节点及其上级节点路径。
使用列表时,还有一个常见的操作是「排序」,但是整棵树「排序」和树形控件本身的层级顺序是相矛盾的。所以「树列表」基本没有「排序」功能。
写在最后
2020 上半年做了很多和「树形控件」相关的项目,想把踩过的坑都记录下来,分享给大家。在这里要感谢一下 Ant Design 的「Tree 树形控件」,如果不是它我还不知道树能玩出这么多花样呢 ♀️。更多系列文章可以移步语雀阅读。
—— 来自一个爱树的设计师