Skip to content

交互规范

源码: 全局交互行为、动效和可访问性规范


触摸交互规范

触摸目标

规范要求约束级别
最小尺寸44 × 44 px (iOS) / 48 × 48 dp (Android)MUST
间距相邻可触摸元素间距 ≥ 8 pxMUST
热区扩展视觉元素 < 最小尺寸时扩展触摸热区SHOULD

触摸反馈

事件反馈时机约束级别
touch start视觉变化立即MUST
touch end恢复原状立即MUST
long press振动 + 上下文菜单500msSHOULD

按压态规范

css
/* Button 按压态 */
.button:active {
  opacity: 0.7;           /* 或 */
  transform: scale(0.98); /* 或 */
  filter: brightness(0.9);
}

/* Card 按压态 */
.card:active {
  transform: scale(0.98);
  box-shadow: /* 增强阴影 */;
}

手势规范

滑动手势

手势方向应用场景约束级别
滑动水平列表项操作MAY
滑动垂直Sheet 关闭MUST
下拉垂直向下刷新内容SHOULD

Sheet 关闭手势

typescript
const sheetGesture = {
  // 关闭阈值
  closeThreshold: 0.3,  // 30% 高度
  
  // 速度检测
  velocityThreshold: 500,  // px/s
  
  // 决策逻辑
  shouldClose: (distance: number, velocity: number, height: number) => {
    if (velocity > velocityThreshold) return true;
    return distance / height >= closeThreshold;
  }
};

禁止行为

行为约束级别
拦截系统缩放手势MUST NOT
拦截系统返回手势MUST NOT
自定义不可预期的手势SHOULD NOT

动效规范

时间曲线

动效类型持续时间缓动函数约束级别
微交互100-150msease-outMUST
页面切换250-350msease-in-outMUST
Sheet 展开300-400msspring(0.8)SHOULD
骨架闪烁1500mslinearSHOULD

页面转场

typescript
// Push 进入
const pushAnimation = {
  entering: {
    transform: 'translateX(0)',
    opacity: 1,
    from: { transform: 'translateX(100%)', opacity: 1 }
  },
  exiting: {
    transform: 'translateX(-30%)',
    opacity: 0.3,
    from: { transform: 'translateX(0)', opacity: 1 }
  }
};

// Pop 返回
const popAnimation = {
  entering: {
    transform: 'translateX(0)',
    opacity: 1,
    from: { transform: 'translateX(-30%)', opacity: 0.3 }
  },
  exiting: {
    transform: 'translateX(100%)',
    opacity: 1,
    from: { transform: 'translateX(0)', opacity: 1 }
  }
};

3D 卡片效果

css
/* 透视容器 */
.perspective-container {
  perspective: 1000px;
}

/* 3D 卡片 */
.card-3d {
  --tilt-x: 0;
  --tilt-y: 0;
  --tilt-intensity: 0;
  
  transform: rotateX(calc(var(--tilt-x) * 1deg)) 
             rotateY(calc(var(--tilt-y) * 1deg));
  transform-style: preserve-3d;
  transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* 参数限制 */
.card-3d {
  --max-tilt: 15;        /* 最大倾斜角度 ±15° */
  --perspective: 1000px; /* 透视距离 */
  --transition: 400ms;   /* 过渡时长 */
}

减少动效模式

约束说明
MUST检测系统 "减少动效" 设置
MUST禁用弹簧动画
MUST使用淡入淡出替代滑动
MUST缩短动画时间至最小
typescript
const prefersReducedMotion = 
  window.matchMedia('(prefers-reduced-motion: reduce)').matches;

const duration = prefersReducedMotion ? 0 : 300;

加载状态规范

骨架屏

适用场景形态约束级别
文本圆角矩形,高度=行高SHOULD
头像圆形SHOULD
卡片与实际尺寸一致SHOULD
列表重复 3-5 个骨架项SHOULD
css
/* 骨架动画 */
@keyframes skeleton-shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.skeleton {
  background: linear-gradient(
    90deg,
    hsl(var(--muted)) 25%,
    hsl(var(--muted) / 0.5) 50%,
    hsl(var(--muted)) 75%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s infinite;
}

加载指示器类型

类型适用场景约束级别
Spinner按钮内、小区域SHOULD
Skeleton页面首次加载SHOULD
Progress已知进度操作MAY

空状态规范

结构

┌─────────────────────────────────┐
│          [插图/图标]             │
│                                 │
│         主标题                   │
│         副标题(可选)           │
│                                 │
│         [操作按钮]               │
└─────────────────────────────────┘

文案规范

元素内容约束级别
主标题描述当前状态MUST
副标题说明原因或引导SHOULD
按钮提供恢复路径SHOULD

反馈规范

Toast 消息

类型图标持续时间约束级别
success2sMUST
error3sMUST
warning3sSHOULD
info2sSHOULD

振动反馈

场景振动类型约束级别
按钮点击lightMAY
操作成功successSHOULD
操作失败errorSHOULD
危险确认warningMUST

振动约束

约束说明
MUST检测系统振动设置
MUST NOT静音模式下振动(除非用户明确开启)

可访问性规范

语义结构

元素语义角色约束级别
导航栏role="navigation"MUST
主内容role="main"MUST
对话框role="dialog"MUST
列表role="list"SHOULD
按钮role="button"MUST

焦点管理

约束说明
MUST遵循视觉阅读顺序
MUST可通过键盘 Tab 遍历
MUST模态对话框内焦点循环
MUST关闭对话框时焦点返回触发元素

屏幕阅读器

约束说明
MUST所有按钮有 accessible name
MUST所有输入框有 label
MUST图标按钮使用 aria-label
SHOULD动态内容使用 aria-live

对比度

元素最小对比度WCAG 级别
正文文本4.5:1AA
大文本 (≥18px)3:1AA
图标3:1AA
禁用状态无要求-

相关文档

Released under the MIT License.