interaction-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseInteraction Patterns
交互设计模式
Codifiable UI interaction patterns that prevent common UX failures. Covers loading states, content pagination, disclosure patterns, overlays, drag-and-drop, tab overflow, and notification systems — all with accessibility baked in.
可编码的UI交互设计模式,可避免常见的UX问题。涵盖加载状态、内容分页、展示模式、覆盖层、拖拽、标签栏溢出以及通知系统——所有模式均内置无障碍支持。
Quick Reference
快速参考
| Rule | File | Impact | When to Use |
|---|---|---|---|
| Skeleton Loading | | HIGH | Content-shaped placeholders for async data |
| Infinite Scroll | | CRITICAL | Paginated content with a11y and keyboard support |
| Progressive Disclosure | | HIGH | Revealing complexity based on user need |
| Modal / Drawer / Inline | | HIGH | Choosing overlay vs inline display patterns |
| Drag & Drop | | CRITICAL | Reorderable lists with keyboard alternatives |
| Tabs Overflow | | MEDIUM | Tab bars with 7+ items or dynamic tabs |
| Toast Notifications | | HIGH | Success/error feedback and notification stacking |
| Cognitive Load Thresholds | | HIGH | Enforcing Miller's Law, Hick's Law, and Doherty Threshold with numeric limits |
| Form UX | | HIGH | Target sizing, label placement, error prevention, and smart defaults |
| Persuasion Ethics | | HIGH | Detecting dark patterns and applying ethical engagement principles |
Total: 10 rules across 6 categories
| 规则 | 文件 | 影响程度 | 适用场景 |
|---|---|---|---|
| 骨架屏加载 | | 高 | 异步数据的内容形状占位符 |
| 无限滚动 | | 关键 | 带a11y及键盘支持的分页内容 |
| 渐进式展示 | | 高 | 根据用户需求逐步展示复杂内容 |
| 模态框/侧边栏/内联展示 | | 高 | 选择覆盖层 vs 内联展示模式 |
| 拖拽功能 | | 关键 | 带键盘替代方案的可重排列表 |
| 标签栏溢出处理 | | 中 | 包含7个以上标签或动态标签的标签栏 |
| 通知提示 | | 高 | 成功/错误反馈及通知堆叠 |
| 认知负荷阈值 | | 高 | 通过数值限制执行米勒定律、希克定律和多尔蒂阈值 |
| 表单UX | | 高 | 目标尺寸、标签布局、错误预防及智能默认值 |
| 说服伦理 | | 高 | 检测暗黑模式并应用伦理参与原则 |
总计:6大类别下的10条规则
Decision Table — Loading States
决策表——加载状态
| Scenario | Pattern | Why |
|---|---|---|
| List/card content loading | Skeleton | Matches content shape, reduces perceived latency |
| Form submission | Spinner | Indeterminate, short-lived action |
| File upload | Progress bar | Measurable operation with known total |
| Image loading | Blur placeholder | Prevents layout shift, progressive reveal |
| Route transition | Skeleton | Preserves layout while data loads |
| Background sync | None / subtle indicator | Non-blocking, low priority |
| 场景 | 模式 | 原因 |
|---|---|---|
| 列表/卡片内容加载 | 骨架屏 | 匹配内容形状,降低感知延迟 |
| 表单提交 | 加载动画 | 不确定时长的短期操作 |
| 文件上传 | 进度条 | 可衡量进度的已知总任务 |
| 图片加载 | 模糊占位符 | 防止布局偏移,渐进式展示 |
| 路由切换 | 骨架屏 | 数据加载时保留布局结构 |
| 后台同步 | 无/细微指示器 | 非阻塞、低优先级任务 |
Quick Start
快速上手
Skeleton Loading
骨架屏加载
tsx
function CardSkeleton() {
return (
<div className="animate-pulse space-y-3">
<div className="h-48 w-full rounded-lg bg-muted" />
<div className="h-4 w-3/4 rounded bg-muted" />
<div className="h-4 w-1/2 rounded bg-muted" />
</div>
)
}
function CardList({ items, isLoading }: { items: Item[]; isLoading: boolean }) {
if (isLoading) {
return (
<div className="grid grid-cols-3 gap-4">
{Array.from({ length: 6 }).map((_, i) => (
<CardSkeleton key={i} />
))}
</div>
)
}
return (
<div className="grid grid-cols-3 gap-4">
{items.map((item) => <Card key={item.id} item={item} />)}
</div>
)
}tsx
function CardSkeleton() {
return (
<div className="animate-pulse space-y-3">
<div className="h-48 w-full rounded-lg bg-muted" />
<div className="h-4 w-3/4 rounded bg-muted" />
<div className="h-4 w-1/2 rounded bg-muted" />
</div>
)
}
function CardList({ items, isLoading }: { items: Item[]; isLoading: boolean }) {
if (isLoading) {
return (
<div className="grid grid-cols-3 gap-4">
{Array.from({ length: 6 }).map((_, i) => (
<CardSkeleton key={i} />
))}
</div>
)
}
return (
<div className="grid grid-cols-3 gap-4">
{items.map((item) => <Card key={item.id} item={item} />)}
</div>
)
}Infinite Scroll with Accessibility
带无障碍支持的无限滚动
tsx
function InfiniteList({ fetchNextPage, hasNextPage, items }: Props) {
const sentinelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting && hasNextPage) fetchNextPage() },
{ rootMargin: "200px" }
)
if (sentinelRef.current) observer.observe(sentinelRef.current)
return () => observer.disconnect()
}, [fetchNextPage, hasNextPage])
return (
<div role="feed" aria-busy={isFetching}>
{items.map((item) => (
<article key={item.id} aria-posinset={item.index} aria-setsize={-1}>
<ItemCard item={item} />
</article>
))}
<div ref={sentinelRef} />
{hasNextPage && (
<button onClick={() => fetchNextPage()}>Load more items</button>
)}
<div aria-live="polite" className="sr-only">
{`Showing ${items.length} items`}
</div>
</div>
)
}tsx
function InfiniteList({ fetchNextPage, hasNextPage, items }: Props) {
const sentinelRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting && hasNextPage) fetchNextPage() },
{ rootMargin: "200px" }
)
if (sentinelRef.current) observer.observe(sentinelRef.current)
return () => observer.disconnect()
}, [fetchNextPage, hasNextPage])
return (
<div role="feed" aria-busy={isFetching}>
{items.map((item) => (
<article key={item.id} aria-posinset={item.index} aria-setsize={-1}>
<ItemCard item={item} />
</article>
))}
<div ref={sentinelRef} />
{hasNextPage && (
<button onClick={() => fetchNextPage()}>Load more items</button>
)}
<div aria-live="polite" className="sr-only">
{`Showing ${items.length} items`}
</div>
</div>
)
}Rule Details
规则详情
Skeleton Loading
骨架屏加载
Content-shaped placeholders that match the final layout. Use skeleton for lists, cards, and text blocks.
Load:rules/interaction-skeleton-loading.md
与最终布局匹配的内容形状占位符。适用于列表、卡片和文本块。
查看详情:rules/interaction-skeleton-loading.md
Infinite Scroll
无限滚动
Accessible infinite scroll with IntersectionObserver, screen reader announcements, and "Load more" fallback.
Load:rules/interaction-infinite-scroll.md
基于IntersectionObserver的无障碍无限滚动,包含屏幕阅读器播报及“加载更多”备选方案。
查看详情:rules/interaction-infinite-scroll.md
Progressive Disclosure
渐进式展示
Reveal complexity progressively: tooltip, accordion, wizard, contextual panel.
Load:rules/interaction-progressive-disclosure.md
逐步展示复杂内容:工具提示、折叠面板、向导流程、上下文面板。
查看详情:rules/interaction-progressive-disclosure.md
Modal / Drawer / Inline
模态框/侧边栏/内联展示
Choose the right overlay pattern: modal for confirmations, drawer for detail views, inline for simple toggles.
Load:rules/interaction-modal-drawer-inline.md
选择合适的覆盖层模式:模态框用于确认操作,侧边栏用于详情查看,内联展示用于简单切换。
查看详情:rules/interaction-modal-drawer-inline.md
Drag & Drop
拖拽功能
Drag-and-drop with mandatory keyboard alternatives using .
@dnd-kit/coreLoad:rules/interaction-drag-drop.md
基于实现的带强制键盘替代方案的拖拽功能。
@dnd-kit/core查看详情:rules/interaction-drag-drop.md
Tabs Overflow
标签栏溢出处理
Scrollable tab bars with overflow menus for dynamic or numerous tabs.
Load:rules/interaction-tabs-overflow.md
针对动态标签或大量标签的可滚动标签栏及溢出菜单。
查看详情:rules/interaction-tabs-overflow.md
Toast Notifications
通知提示
Positioned, auto-dismissing notifications with ARIA roles and stacking.
Load:rules/interaction-toast-notifications.md
带定位、自动关闭功能的通知,包含ARIA角色及堆叠支持。
查看详情:rules/interaction-toast-notifications.md
Cognitive Load Thresholds
认知负荷阈值
Miller's Law (max 7 items per group), Hick's Law (max 1 primary CTA), and Doherty Threshold (400ms feedback) with specific, countable limits.
Load:rules/interaction-cognitive-load-thresholds.md
米勒定律(每组最多7个选项)、希克定律(最多1个主要CTA)和多尔蒂阈值(400ms反馈)的具体数值限制。
查看详情:rules/interaction-cognitive-load-thresholds.md
Form UX
表单UX
Fitts's Law touch targets (44px mobile), top-aligned labels, Poka-Yoke error prevention with blur-only validation, and smart defaults.
Load:rules/interaction-form-ux.md
基于菲茨定律的触摸目标(移动端44px)、顶部对齐标签、防错设计的失焦验证及智能默认值。
查看详情:rules/interaction-form-ux.md
Persuasion Ethics
说服伦理
13 dark pattern red flags to detect and reject, the Hook Model ethical test (aware, reversible, user-benefits), and EU DSA Art. 25 compliance.
Load:rules/interaction-persuasion-ethics.md
13种需识别并拒绝的暗黑模式红牌、钩子模型伦理测试(知情、可逆、用户受益)以及欧盟DSA第25条合规要求。
查看详情:rules/interaction-persuasion-ethics.md
Key Principles
核心原则
- Keyboard parity — Every mouse interaction MUST have a keyboard equivalent. No drag-only, no hover-only.
- Skeleton over spinner — Use content-shaped placeholders for data loading; reserve spinners for indeterminate actions.
- Native HTML first — Prefer ,
<dialog>,<details>over custom implementations.role="feed" - Progressive enhancement — Features should work without JS where possible, then enhance with interaction.
- Announce state changes — Use regions to announce dynamic content changes to screen readers.
aria-live - Respect scroll position — Back navigation must restore scroll position; infinite scroll must not lose user's place.
- 键盘对等性——所有鼠标交互必须有对应的键盘操作方式。不允许仅支持拖拽或仅支持悬停的交互。
- 优先使用骨架屏而非加载动画——数据加载时使用内容形状占位符;加载动画仅用于不确定时长的操作。
- 优先使用原生HTML——优先使用、
<dialog>、<details>而非自定义实现。role="feed" - 渐进式增强——功能应在无JS环境下可正常使用,再通过交互进行增强。
- 播报状态变化——使用区域向屏幕阅读器播报动态内容变化。
aria-live - 尊重滚动位置——返回导航必须恢复滚动位置;无限滚动不得丢失用户当前位置。
Anti-Patterns (FORBIDDEN)
反模式(禁止使用)
- Spinner for content loading — Spinners give no spatial hint. Use skeletons matching the content shape.
- Infinite scroll without Load More — Screen readers and keyboard users cannot reach footer content. Always provide a button fallback.
- Modal for browsable content — Modals trap focus and block interaction. Use drawers or inline expansion for browsing.
- Drag-only reorder — Excludes keyboard and assistive tech users. Always provide arrow key + Enter alternatives.
- Toast without ARIA role — Toasts are invisible to screen readers. Use for success,
role="status"for errors.role="alert" - Auto-dismiss error toasts — Users need time to read errors. Never auto-dismiss error notifications.
- 内容加载使用加载动画——加载动画无法提供空间提示。应使用匹配内容形状的骨架屏。
- 无限滚动无“加载更多”按钮——屏幕阅读器和键盘用户无法触达页脚内容。必须提供按钮备选方案。
- 可浏览内容使用模态框——模态框会锁定焦点并阻止交互。浏览内容应使用侧边栏或内联展开。
- 仅支持拖拽的重排功能——排除了键盘及辅助技术用户。必须提供方向键+回车的替代方案。
- 无ARIA角色的通知提示——通知提示对屏幕阅读器不可见。成功提示使用,错误提示使用
role="status"。role="alert" - 错误提示自动关闭——用户需要时间阅读错误信息。禁止自动关闭错误通知。
Detailed Documentation
详细文档
| Resource | Description |
|---|---|
| references/loading-states-decision-tree.md | Decision tree for skeleton vs spinner vs progress bar |
| references/interaction-pattern-catalog.md | Catalog of 15+ interaction patterns with when-to-use guidance |
| references/keyboard-interaction-matrix.md | Keyboard shortcuts matrix for all interactive patterns (WAI-ARIA APG) |
| 资源 | 说明 |
|---|---|
| references/loading-states-decision-tree.md | 骨架屏vs加载动画vs进度条的决策树 |
| references/interaction-pattern-catalog.md | 包含15+种交互模式及适用场景的目录 |
| references/keyboard-interaction-matrix.md | 所有交互模式的键盘快捷键矩阵(符合WAI-ARIA APG) |
Related Skills
相关技能
- — shadcn/ui component patterns and CVA variants
ork:ui-components - — Motion library and View Transitions API
ork:animation-motion-design - — WCAG compliance, ARIA patterns, screen reader support
ork:accessibility - — Responsive layout and container query patterns
ork:responsive-patterns - — Core Web Vitals and runtime performance optimization
ork:performance
- — shadcn/ui组件模式及CVA变体
ork:ui-components - — 动效库及View Transitions API
ork:animation-motion-design - — WCAG合规、ARIA模式、屏幕阅读器支持
ork:accessibility - — 响应式布局及容器查询模式
ork:responsive-patterns - — Core Web Vitals及运行时性能优化
ork:performance