https://interfaces.rauno.me/
这个文档概述了构建良好的用户界面的一些细节,文档在持续更新中。本文借助 chatgpt 以及个人修改进行翻译,有些其实没接触过的,我也不懂啥意思,建议看原文。
# 交互
- 点击输入框就聚焦输入
- 输入框应该被 form 元素包括,enter 件可以提交
- 输入框应该包含 type 属性,例如 password、email
- 大部分时间,输入框不应该使用拼写检查(spellcheck)以及自动填充(autocomplete)
- 需要校验的时候,使用 required 来校验
- 输入前缀和后缀装饰,比如图标、应该绝对定位,应该添加内边距,层级放在输入框上方,而不要放在旁边,点击也可以聚焦到输入框
- toggle 组件必须立即生效,不需要二次确认
- 按钮应该在提交后失效,避免重复提交 (或者 loading)
- 交互的组件应该设置 user-select 为 none
- 装饰元素应该禁用指针事件,避免干扰
- 垂直或者水平列表中的可交互元素之间不应存在无效区域,同时应该增加元素内边距增大可点击区域
# 排版
-
- 字体应该应用
-webkit-font-smoothing: antialiased
以提高可读性
- 字体应该应用
-
字体应该应用
text-rendering: optimizeLegibility
以提高可读性 -
字体应该根据内容、字母表或相关语言进行子集化
-
在鼠标悬停或选中状态下不应改变字体粗细,以避免布局变化
-
不应使用低于 400 的字体粗细
-
中等大小的标题通常在 500-600 的字体粗细之间效果最好
-
通过使用 CSS 的
clamp()
函数动态调整数值,例如clamp(48px, 5vw, 72px)
,可应用于标题的字体大小
clamp()
CSS 函数将中间值限制在指定的最小值和最大值范围内。该函数接受三个参数:最小值、首选值和最大允许值。
换句话说,clamp()
函数确保结果值落在指定的范围内。如果首选值在最小值和最大值之间,则直接返回首选值。如果首选值小于最小值,则返回最小值。同样地,如果首选值大于最大值,则返回最大值。
以下是使用clamp()
函数的语法:
clamp(最小值, 首选值, 最大值)
例如,clamp(10px, 5vw, 20px)
将返回至少为 10 像素,但不超过 20 像素的值。如果首选值5vw
在指定的范围内,将使用它作为结果值。
这个函数在创建响应式设计时非常有用,其中某个值应根据视口大小进行缩放,但仍有定义的限制。 -
在可用时,应使用
font-variant-numeric: tabular-nums
应用表格数字,特别是在表格或不希望出现布局变化的情况下,例如计时器中 -
使用
-webkit-text-size-adjust: 100%
可防止在 iOS 的横向模式下出现意外的文本调整大小
# Motion (动画)
- 切换主题不应触发元素 transition 或者动画
- 动画不应超过 200ms,否则会影响交互速度
- 动画值应该和触发器大小成比例:
- 缩放动画不应从 0 到 1,而是从 0.8 开始渐变透明度或者缩放度
- 按钮激活动画不应从 1 到 0.8,而是到 0.96 0.9 等等
- 频率较高的动作避免不必要的动画
- 例如右键菜单
- 删除或者添加列表项
- 一般的按钮
- 看不见的元素动画应该停止,以降低 cpu 和 gpu 的能耗
- 使用 scroll-behavior:smooth 来作为业内导航的参数
# 触摸 (移动设备)
- 触摸时不应显示悬停状态,使用
@media (hover: hover)
来实现。 - 输入框字体不小于 16px,防止 ios 焦点状态下缩放
- 输入框不应自动获取焦点
- video,应使用
muted
和playsinline
属性以在 iOS 上自动播放 - 对于自定义组件实现了平移和缩放手势的情况,应禁用
touch-action
属性,以防止与缩放和滚动等本机行为的干扰 - 使用
-webkit-tap-highlight-color: rgba(0,0,0,0)
可以禁用默认的 iOS 点击高亮效果,但始终应替代为适当的替代方案
# 优化
- 使用较大的
blur()
值来设置filter
和backdrop-filter
可能会导致性能下降 - 矩形缩放和模糊处理会导致色带效应(banding),使用径向渐变比较好
- 谨慎使用
transform: translateZ(0)
来启用 GPU 渲染,以提高性能,但仅适用于性能较差的动画 - 对于性能较差的滚动动画,在动画的持续时间内切换
will-change
属性 - 播放过多的视频可能会导致 iOS 设备性能下降,建议对屏幕外的视频进行暂停甚至卸载
- 使用
refs
绕过 React 的渲染生命周期,直接将实时值提交给 DOM - 检测和适应用户设备的硬件和网络能力
# 友好设计
- 禁用的按钮不应有提示信息
- 焦点环使用 box-shadow 而不是 outline
- 列表可聚焦元素支持上下键切换
- 列表可聚焦元素支持删除键删除
- 下拉菜单触发应该是 onMouseDown 而不是 onClick 事件
- 使用带有样式标签的 SVG 网站图标,根据 prefers-color-scheme 遵循系统主题
- 仅包含图标的交互元素应该定义一个明确的
aria-label
(这样会支持屏幕阅读工具阅读) - 悬浮触发的 tip 不应包含交互内容
- 图片使用 img 渲染,方便复制
- 插图应该有 aria-label
- 渐变文本在
::selection
状态下应取消渐变效果 - 当使用嵌套菜单时,使用 "prediction cone” 以防止指针在移动过程中意外关闭菜单
# 设计
- 提交后数据更新;但服务器报错后进行回滚和提示
- 身份验证应该在服务器完成,避免 url 变化
- 使用
::selection
样式化文档选中状态 - 显示反馈:
- 复制成功时,显示一个内联的标记,而不是一个通知
- 输入错误时高亮显示相关的输入框
- 空状态应提示创建新项,并可选择使用模板