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,应使用 mutedplaysinline 属性以在 iOS 上自动播放
  • 对于自定义组件实现了平移和缩放手势的情况,应禁用 touch-action 属性,以防止与缩放和滚动等本机行为的干扰
  • 使用 -webkit-tap-highlight-color: rgba(0,0,0,0) 可以禁用默认的 iOS 点击高亮效果,但始终应替代为适当的替代方案

# 优化

  • 使用较大的 blur() 值来设置 filterbackdrop-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 样式化文档选中状态
  • 显示反馈:
    • 复制成功时,显示一个内联的标记,而不是一个通知
    • 输入错误时高亮显示相关的输入框
  • 空状态应提示创建新项,并可选择使用模板