web-design-guidelines

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Web Interface Design Guidelines

Web界面设计指南

Comprehensive code review for web interface compliance with industry standards including WCAG 2.2, Core Web Vitals, and modern UX best practices.
针对Web界面符合行业标准(包括WCAG 2.2、Core Web Vitals及现代UX最佳实践)的全面代码审查。

Summary

概述

Goal: Review UI code for compliance with WCAG 2.2 accessibility, responsive design, performance (Core Web Vitals), and modern UX best practices.
StepActionKey Notes
1Read specified filesOr prompt user for files/pattern
2Check against all rulesAccessibility, responsive, performance, usability
3Output findingsTerse
file:line
format, grouped by file
4Skip explanationsUnless fix is non-obvious
Key Principles:
  • Semantic HTML first — use native elements over ARIA whenever possible
  • Minimum 4.5:1 contrast ratio for normal text, 3:1 for large text
  • All interactive elements must be keyboard accessible with visible focus states
目标: 审查UI代码是否符合WCAG 2.2可访问性、响应式设计、性能(Core Web Vitals)及现代UX最佳实践要求。
步骤操作关键说明
1读取指定文件或提示用户提供文件/匹配模式
2对照所有规则检查可访问性、响应式、性能、可用性
3输出检查结果采用简洁的
file:line
格式,按文件分组
4跳过解释除非修复方案不明确
核心原则:
  • 优先使用语义化HTML — 只要可能,就用原生元素替代ARIA
  • 普通文本的对比度至少为4.5:1,大文本至少为3:1
  • 所有交互元素必须支持键盘访问,并带有可见的焦点状态

How to Use

使用方法

  1. Read the specified files (or prompt user for files/pattern)
  2. Check against all rules below
  3. Output findings in terse
    file:line
    format
  4. Group by file, state issue + location, skip explanations unless fix is non-obvious

  1. 读取指定文件(或提示用户提供文件/匹配模式)
  2. 对照以下所有规则进行检查
  3. 以简洁的
    file:line
    格式输出结果
  4. 按文件分组,说明问题及位置,除非修复方案不明确,否则跳过解释

1. Accessibility (WCAG 2.2 Compliance)

1. 可访问性(符合WCAG 2.2标准)

1.1 Semantic HTML (First Rule)

1.1 语义化HTML(首要规则)

"If you can use a native HTML element with built-in semantics, use it instead of ARIA."
  • Use
    <button>
    for actions,
    <a>
    /
    <Link>
    for navigation (NEVER
    <div onClick>
    or
    <span onClick>
    )
  • Use semantic containers:
    <header>
    ,
    <main>
    ,
    <nav>
    ,
    <footer>
    ,
    <aside>
    ,
    <section>
    ,
    <article>
  • Use heading hierarchy
    <h1>
    <h6>
    in logical order (no skipping levels)
  • Use
    <label>
    with
    for
    /
    htmlFor
    for form controls
  • Use
    <table>
    for tabular data (not CSS grids for data tables)
  • Use
    <ul>
    /
    <ol>
    for lists
  • Include skip link to main content:
    <a href="#main">Skip to content</a>
“如果可以使用带有内置语义的原生HTML元素,就用它替代ARIA。”
  • 操作类使用
    <button>
    ,导航类使用
    <a>
    /
    <Link>
    (绝对不要用
    <div onClick>
    <span onClick>
  • 使用语义化容器:
    <header>
    <main>
    <nav>
    <footer>
    <aside>
    <section>
    <article>
  • 按逻辑顺序使用标题层级
    <h1>
    <h6>
    (不要跳过层级)
  • 表单控件使用带
    for
    /
    htmlFor
    属性的
    <label>
  • 表格数据使用
    <table>
    (不要用CSS网格实现数据表格)
  • 列表使用
    <ul>
    /
    <ol>
  • 添加跳转到主内容的链接:
    <a href="#main">跳转到内容</a>

1.2 ARIA Usage

1.2 ARIA使用规范

"No ARIA is better than bad ARIA" – Sites with ARIA average 41% more errors than those without.
  • Only use ARIA when no native HTML equivalent exists (custom widgets like tabs, trees, comboboxes)
  • Icon-only buttons MUST have
    aria-label
    :
    <button aria-label="Close">
  • Decorative icons MUST have
    aria-hidden="true"
  • Async updates (toasts, validation) MUST use
    aria-live="polite"
    (reserve
    assertive
    for critical errors)
  • Collapsed sections need
    aria-expanded="false"
    , expanded need
    aria-expanded="true"
  • Hidden elements need
    aria-hidden="true"
    to exclude from screen readers
  • Invalid form fields need
    aria-invalid="true"
  • Required fields need
    aria-required="true"
    or HTML
    required
“没有ARIA比错误使用ARIA更好” — 使用ARIA的站点比不使用的站点平均多41%的错误。
  • 仅在没有原生HTML等效元素时使用ARIA(如自定义选项卡、树形控件、组合框等小部件)
  • 纯图标按钮必须带有
    aria-label
    <button aria-label="关闭">
  • 装饰性图标必须设置
    aria-hidden="true"
  • 异步更新(提示框、验证信息)必须使用
    aria-live="polite"
    assertive
    仅用于关键错误)
  • 折叠区域需要设置
    aria-expanded="false"
    ,展开时设置
    aria-expanded="true"
  • 隐藏元素需要设置
    aria-hidden="true"
    以排除在屏幕阅读器之外
  • 无效的表单字段需要设置
    aria-invalid="true"
  • 必填字段需要设置
    aria-required="true"
    或HTML的
    required
    属性

1.3 Images & Media

1.3 图片与媒体

  • All
    <img>
    MUST have
    alt
    attribute
  • Decorative images:
    alt=""
    (empty, not missing)
  • Informative images: descriptive
    alt
    text explaining content/purpose
  • Complex images (charts, diagrams): provide long description or
    aria-describedby
  • Background images with meaning: provide text alternative nearby
  • Video: provide captions and transcripts
  • Audio: provide transcripts
  • 所有
    <img>
    必须带有
    alt
    属性
  • 装饰性图片:
    alt=""
    (空值,不要缺失)
  • 信息性图片:使用描述性的
    alt
    文本说明内容/用途
  • 复杂图片(图表、示意图):提供详细描述或使用
    aria-describedby
  • 有意义的背景图片:在附近提供文本替代方案
  • 视频:提供字幕和文字记录
  • 音频:提供文字记录

1.4 Color & Contrast

1.4 颜色与对比度

  • Normal text: minimum 4.5:1 contrast ratio
  • Large text (18px+ or 14px+ bold): minimum 3:1 contrast ratio
  • UI components (buttons, inputs, icons): minimum 3:1 contrast ratio
  • NEVER rely solely on color to convey meaning (add icons, text, or patterns)
  • Test with colorblind simulation tools
  • Error states: don't just use red—add icons or text

  • 普通文本:对比度至少为4.5:1
  • 大文本(18px以上或14px以上加粗):对比度至少为3:1
  • UI组件(按钮、输入框、图标):对比度至少为3:1
  • 绝对不要仅依赖颜色传达信息(添加图标、文本或图案)
  • 使用色盲模拟工具测试
  • 错误状态:不要只使用红色——添加图标或文本

2. Focus & Keyboard Navigation

2. 焦点与键盘导航

2.1 Focus Visibility

2.1 焦点可见性

  • Interactive elements MUST have visible focus indicator
  • NEVER use
    outline: none
    or
    outline-none
    without replacement
  • Use
    :focus-visible
    over
    :focus
    (avoids focus ring on click)
  • Focus indicator minimum: 2px thick, 3:1 contrast against adjacent colors
  • Use
    focus-visible:ring-*
    (Tailwind) or custom focus styles
  • Group related controls with
    :focus-within
  • 交互元素必须带有可见的焦点指示器
  • 绝对不要在没有替代方案的情况下使用
    outline: none
    outline-none
  • 优先使用
    :focus-visible
    而非
    :focus
    (避免点击时显示焦点环)
  • 焦点指示器最小要求:2px粗,与相邻颜色的对比度为3:1
  • 使用
    focus-visible:ring-*
    (Tailwind)或自定义焦点样式
  • 使用
    :focus-within
    对相关控件进行分组

2.2 Keyboard Accessibility

2.2 键盘可访问性

  • ALL interactive elements must be reachable via Tab/Shift+Tab
  • Logical tab order matching visual layout
  • Custom widgets need keyboard handlers:
    onKeyDown
    /
    onKeyUp
  • Modals/dialogs: trap focus inside, return focus on close
  • Collapsible elements: Enter/Space to toggle
  • Escape key should close modals, dropdowns, tooltips
  • Never use
    tabindex
    > 0 (disrupts natural order)
  • tabindex="-1"
    for programmatically focusable but not tabbable elements
  • tabindex="0"
    to make non-interactive elements focusable (when ARIA role requires it)

  • 所有交互元素必须可通过Tab/Shift+Tab访问
  • 逻辑Tab顺序与视觉布局匹配
  • 自定义小部件需要键盘处理程序:
    onKeyDown
    /
    onKeyUp
  • 模态框/对话框:将焦点限制在内部,关闭时返回焦点
  • 可折叠元素:按Enter/Space键切换状态
  • Escape键应关闭模态框、下拉菜单、工具提示
  • 绝对不要使用
    tabindex
    > 0(会打乱自然顺序)
  • tabindex="-1"
    用于可通过编程聚焦但不能通过Tab聚焦的元素
  • tabindex="0"
    用于需要聚焦的非交互元素(当ARIA角色要求时)

3. Forms

3. 表单

3.1 Labels & Association

3.1 标签与关联

  • Every input MUST have a visible
    <label>
    with
    for
    /
    htmlFor
    matching input
    id
  • OR wrap input inside
    <label>
    element
  • Placeholder is NOT a substitute for label
  • Group related inputs with
    <fieldset>
    and
    <legend>
  • Checkboxes/radios: label + control share single hit target (no dead zones)
  • 每个输入框必须带有可见的
    <label>
    ,其
    for
    /
    htmlFor
    属性与输入框的
    id
    匹配
  • 或者将输入框包裹在
    <label>
    元素内
  • 占位符不能替代标签
  • 使用
    <fieldset>
    <legend>
    对相关输入框进行分组
  • 复选框/单选框:标签与控件共享单个点击区域(无无效区域)

3.2 Input Attributes

3.2 输入框属性

  • Use correct
    type
    :
    email
    ,
    tel
    ,
    url
    ,
    number
    ,
    password
    ,
    search
    ,
    date
  • Use
    inputmode
    for mobile keyboards:
    numeric
    ,
    tel
    ,
    email
    ,
    url
    ,
    decimal
  • Use meaningful
    name
    attributes
  • Use
    autocomplete
    for common fields:
    name
    ,
    email
    ,
    tel
    ,
    street-address
    ,
    postal-code
    ,
    cc-number
  • Use
    autocomplete="off"
    on non-auth fields to avoid password manager triggers
  • Disable
    spellCheck
    on emails, codes, usernames:
    spellCheck={false}
  • 使用正确的
    type
    email
    tel
    url
    number
    password
    search
    date
  • 为移动键盘使用
    inputmode
    numeric
    tel
    email
    url
    decimal
  • 使用有意义的
    name
    属性
  • 为常见字段使用
    autocomplete
    name
    email
    tel
    street-address
    postal-code
    cc-number
  • 在非认证字段上使用
    autocomplete="off"
    以避免触发密码管理器
  • 在邮箱、代码、用户名上禁用
    spellCheck
    spellCheck={false}

3.3 Validation & Error Handling

3.3 验证与错误处理

  • NEVER block paste: no
    onPaste
    +
    preventDefault()
  • Show inline errors next to the field, not just at form top
  • Focus first error on submit
  • Use
    aria-invalid="true"
    and
    aria-describedby
    for error messages
  • Submit button stays enabled until request starts; show spinner during request
  • Warn before navigation with unsaved changes (
    beforeunload
    or router guard)
  • 绝对不要阻止粘贴:不要使用
    onPaste
    +
    preventDefault()
  • 在字段旁边显示内联错误,而不仅仅在表单顶部
  • 提交时聚焦第一个错误字段
  • 对错误消息使用
    aria-invalid="true"
    aria-describedby
  • 提交按钮在请求开始前保持启用状态;请求期间显示加载动画
  • 有未保存更改时,在导航前发出警告(使用
    beforeunload
    或路由守卫)

3.4 Placeholders

3.4 占位符

  • Placeholders should show example format, not instructions
  • End with ellipsis:
    "Search…"
    ,
    "e.g., john@example.com"
  • Placeholder contrast: minimum 4.5:1 (don't use light gray)

  • 占位符应显示示例格式,而非说明文字
  • 以省略号结尾:
    "搜索…"
    "例如:john@example.com"
  • 占位符对比度:至少为4.5:1(不要使用浅灰色)

4. Animation & Motion

4. 动画与动效

4.1 Reduced Motion (REQUIRED)

4.1 减少动效(必填)

css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
  • Honor
    prefers-reduced-motion
    media query
  • Provide reduced alternative (fade instead of slide) or disable animation
  • Test: Windows Settings → Accessibility → Animation effects OFF
  • Test: Mac System Settings → Accessibility → Display → Reduce motion ON
css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
  • 遵循
    prefers-reduced-motion
    媒体查询
  • 提供简化替代方案(用淡入替代滑动)或禁用动画
  • 测试:Windows设置 → 辅助功能 → 动画效果 关闭
  • 测试:Mac系统设置 → 辅助功能 → 显示 → 减少动效 开启

4.2 Performance-Safe Animations

4.2 性能安全的动画

  • ONLY animate
    transform
    and
    opacity
    (GPU-accelerated, no reflows)
  • NEVER animate:
    width
    ,
    height
    ,
    top
    ,
    left
    ,
    margin
    ,
    padding
    ,
    font-size
  • NEVER use
    transition: all
    — list properties explicitly:
    transition: transform 200ms, opacity 200ms
  • Set correct
    transform-origin
  • SVG transforms: use
    <g>
    wrapper with
    transform-box: fill-box; transform-origin: center
  • 仅对
    transform
    opacity
    设置动画(GPU加速,不会导致重排)
  • 绝对不要对以下属性设置动画:
    width
    height
    top
    left
    margin
    padding
    font-size
  • 绝对不要使用
    transition: all
    — 明确列出属性:
    transition: transform 200ms, opacity 200ms
  • 设置正确的
    transform-origin
  • SVG变换:使用
    <g>
    包裹,并设置
    transform-box: fill-box; transform-origin: center

4.3 Timing Guidelines

4.3 时长指南

  • Micro-interactions (buttons, hovers): 100-200ms
  • Small UI changes (tooltips, dropdowns): 200-300ms
  • Medium transitions (modals, panels): 300-500ms
  • Large movements (page transitions): 500-800ms
  • Anything over 1 second feels slow
  • Animations should be interruptible — respond to user input mid-animation

  • 微交互(按钮、悬停):100-200ms
  • 小型UI变化(工具提示、下拉菜单):200-300ms
  • 中型过渡(模态框、面板):300-500ms
  • 大型移动(页面过渡):500-800ms
  • 超过1秒会让人感觉缓慢
  • 动画应可中断 — 在动画过程响应用户输入

5. Typography

5. 排版

5.1 Font Sizes

5.1 字体大小

  • Body text: minimum 16px (1rem)
  • Mobile: 14-16px minimum
  • Use relative units:
    rem
    ,
    em
    ,
    %
    (not
    px
    on root
    <html>
    )
  • Allow text to scale to 200% without loss of content (WCAG requirement)
  • 正文字体:最小16px(1rem)
  • 移动端:最小14-16px
  • 使用相对单位:
    rem
    em
    %
    (不要在根
    <html>
    上使用
    px
  • 允许文本缩放至200%而不丢失内容(WCAG要求)

5.2 Line Height & Length

5.2 行高与行宽

  • Body text:
    line-height: 1.5
    minimum (WCAG AA)
  • Headings:
    line-height: 1.2-1.35
  • Optimal line length: 50-75 characters (66 is sweet spot)
  • Mobile: 30-50 characters per line
  • Use
    max-width: 65ch
    or similar for text containers
  • 正文字体:
    line-height: 1.5
    (WCAG AA级要求最小值)
  • 标题:
    line-height: 1.2-1.35
  • 最佳行宽:50-75个字符(66为最佳值)
  • 移动端:每行30-50个字符
  • 对文本容器使用
    max-width: 65ch
    或类似设置

5.3 Typography Characters

5.3 排版字符

  • Use proper ellipsis:
    not
    ...
  • Use curly quotes:
    "
    "
    '
    '
    not straight quotes
    "
    '
  • Use non-breaking spaces where needed:
    10&nbsp;MB
    ,
    ⌘&nbsp;K
    , brand names
  • Loading states end with ellipsis:
    "Loading…"
    ,
    "Saving…"
  • 使用正确的省略号:
    而非
    ...
  • 使用弯引号:
    而非直引号
    "
    '
  • 在需要的地方使用不间断空格:
    10&nbsp;MB
    ⌘&nbsp;K
    、品牌名称
  • 加载状态以省略号结尾:
    "加载中…"
    "保存中…"

5.4 Number Formatting

5.4 数字格式化

  • Use
    font-variant-numeric: tabular-nums
    for number columns, comparisons, counters
  • Use
    text-wrap: balance
    or
    text-wrap: pretty
    on headings (prevents widows/orphans)
  • 对数字列、比较内容、计数器使用
    font-variant-numeric: tabular-nums
  • 对标题使用
    text-wrap: balance
    text-wrap: pretty
    (防止孤行/寡行)

5.5 Font Loading

5.5 字体加载

  • Limit to 2-3 font families
  • Limit to 3 font weights per family
  • Use
    font-display: swap
    for custom fonts
  • Provide fallback font stack
  • Preload critical fonts:
    <link rel="preload" as="font" crossorigin>

  • 限制为2-3种字体族
  • 每个字体族限制为3种字重
  • 对自定义字体使用
    font-display: swap
  • 提供备用字体栈
  • 预加载关键字体:
    <link rel="preload" as="font" crossorigin>

6. Content Handling

6. 内容处理

6.1 Text Overflow

6.1 文本溢出

  • Text containers must handle long content:
    • truncate
      /
      text-overflow: ellipsis
    • line-clamp-*
      /
      -webkit-line-clamp
    • break-words
      /
      word-break: break-word
  • Flex children need
    min-w-0
    /
    min-width: 0
    to allow text truncation
  • Test with very long strings (50+ chars without spaces)
  • 文本容器必须能处理长内容:
    • truncate
      /
      text-overflow: ellipsis
    • line-clamp-*
      /
      -webkit-line-clamp
    • break-words
      /
      word-break: break-word
  • Flex子元素需要
    min-w-0
    /
    min-width: 0
    以允许文本截断
  • 用超长字符串(50个以上无空格字符)测试

6.2 Empty States

6.2 空状态

  • Handle empty strings, null, undefined gracefully
  • Handle empty arrays — show meaningful empty state, not broken UI
  • Anticipate: short, average, and very long user inputs
  • 优雅处理空字符串、null、undefined
  • 处理空数组 — 显示有意义的空状态,而非损坏的UI
  • 提前考虑:短、平均、超长用户输入

6.3 Content Guidelines

6.3 内容指南

  • Active voice: "Install the CLI" not "The CLI will be installed"
  • Title Case for headings and buttons (Chicago style)
  • Use numerals: "8 deployments" not "eight deployments"
  • Specific button labels: "Save API Key" not "Continue" or "Submit"
  • Error messages include fix/next step, not just the problem
  • Use second person ("you"); avoid first person ("I", "we")
  • Use
    &
    over "and" where space-constrained

  • 使用主动语态:“安装CLI”而非“CLI将被安装”
  • 标题和按钮使用标题大小写(芝加哥格式)
  • 使用数字:“8次部署”而非“八次部署”
  • 按钮标签要具体:“保存API密钥”而非“继续”或“提交”
  • 错误信息要包含修复/下一步操作,而不仅仅是问题描述
  • 使用第二人称(“你”);避免第一人称(“我”、“我们”)
  • 空间有限时使用
    &
    替代“和”

7. Images & Media

7. 图片与媒体

7.1 Dimensions & Layout Shift

7.1 尺寸与布局偏移

  • <img>
    MUST have explicit
    width
    and
    height
    attributes (prevents CLS)
  • Or use
    aspect-ratio
    CSS property
  • Reserve space with container aspect ratio
  • <img>
    必须带有明确的
    width
    height
    属性(防止CLS)
  • 或使用
    aspect-ratio
    CSS属性
  • 为容器预留宽高比空间

7.2 Loading Strategy

7.2 加载策略

  • Below-fold images:
    loading="lazy"
  • Above-fold critical images:
    fetchpriority="high"
    or framework's
    priority
  • Use
    decoding="async"
    for non-critical images
  • 首屏以下的图片:
    loading="lazy"
  • 首屏关键图片:
    fetchpriority="high"
    或框架的
    priority
    属性
  • 对非关键图片使用
    decoding="async"

7.3 Optimization

7.3 优化

  • Use modern formats: WebP, AVIF
  • Provide responsive images with
    srcset
    and
    sizes
  • Compress images appropriately
  • Use CDN for image delivery

  • 使用现代格式:WebP、AVIF
  • 提供带
    srcset
    sizes
    的响应式图片
  • 适当压缩图片
  • 使用CDN交付图片

8. Performance (Core Web Vitals)

8. 性能(Core Web Vitals)

8.1 LCP (Largest Contentful Paint)

8.1 LCP(最大内容绘制)

  • Target: < 2.5 seconds
  • Preload critical resources:
    <link rel="preload">
  • Add
    <link rel="preconnect">
    for CDN/asset domains
  • Optimize largest image/text block
  • 目标:< 2.5秒
  • 预加载关键资源:
    <link rel="preload">
  • 为CDN/资源域名添加
    <link rel="preconnect">
  • 优化最大的图片/文本块

8.2 CLS (Cumulative Layout Shift)

8.2 CLS(累积布局偏移)

  • Target: < 0.1
  • Always specify image/video dimensions
  • Reserve space for dynamic content (ads, embeds)
  • Use
    scroll-margin-top
    on heading anchors
  • Avoid inserting content above existing content
  • 目标:< 0.1
  • 始终指定图片/视频尺寸
  • 为动态内容(广告、嵌入内容)预留空间
  • 对标题锚点使用
    scroll-margin-top
  • 避免在现有内容上方插入内容

8.3 INP (Interaction to Next Paint)

8.3 INP(交互到下一次绘制的时间)

  • Target: < 200ms
  • No layout reads during render: avoid
    getBoundingClientRect
    ,
    offsetHeight
    ,
    offsetWidth
    ,
    scrollTop
    in render path
  • Batch DOM reads/writes — don't interleave
  • Prefer uncontrolled inputs; controlled inputs must be cheap per keystroke
  • Debounce expensive handlers
  • 目标:< 200ms
  • 渲染期间不要读取布局:避免在渲染路径中使用
    getBoundingClientRect
    offsetHeight
    offsetWidth
    scrollTop
  • 批量处理DOM读取/写入 — 不要交替进行
  • 优先使用非受控输入;受控输入每次按键的开销必须很低
  • 对昂贵的处理函数进行防抖

8.4 Lists & Virtualization

8.4 列表与虚拟化

  • Large lists (>50 items): virtualize with
    virtua
    ,
    react-window
    ,
    @tanstack/virtual
    , or
    content-visibility: auto
  • Paginate or infinite scroll for large datasets

  • 大型列表(>50项):使用
    virtua
    react-window
    @tanstack/virtual
    content-visibility: auto
    实现虚拟化
  • 大型数据集使用分页或无限滚动

9. Navigation & State

9. 导航与状态

9.1 URL Reflects State

9.1 URL反映状态

  • Filters, tabs, pagination, sort order → URL query params
  • Deep-link all stateful UI (if uses
    useState
    , consider URL sync)
  • Use libraries like
    nuqs
    ,
    next-usequerystate
    , or router state
  • 筛选器、选项卡、分页、排序顺序 → URL查询参数
  • 所有有状态的UI都要支持深度链接(如果使用
    useState
    ,考虑与URL同步)
  • 使用
    nuqs
    next-usequerystate
    或路由状态等库

9.2 Links vs Buttons

9.2 链接与按钮

  • Links (
    <a>
    /
    <Link>
    ) for navigation — supports Cmd/Ctrl+click, middle-click, right-click → "Open in new tab"
  • Buttons (
    <button>
    ) for actions that don't navigate
  • 链接(
    <a>
    /
    <Link>
    )用于导航 — 支持Cmd/Ctrl+点击、中键点击、右键→“在新标签页打开”
  • 按钮(
    <button>
    )用于不涉及导航的操作

9.3 Destructive Actions

9.3 破坏性操作

  • Destructive actions need confirmation modal OR undo window
  • NEVER immediate deletion without recovery option
  • Show clear warning about consequences

  • 破坏性操作需要确认模态框或撤销窗口
  • 绝对不要立即删除而不提供恢复选项
  • 清楚显示关于后果的警告

10. Touch & Mobile Interaction

10. 触摸与移动端交互

10.1 Touch Targets

10.1 触摸目标

  • Minimum touch target: 44×44px (Apple HIG) or 48×48dp (Material)
  • WCAG 2.2: minimum 24×24 CSS pixels
  • Adequate spacing between targets (8px+ gap)
  • 触摸目标最小尺寸:44×44px(Apple HIG)或48×48dp(Material Design)
  • WCAG 2.2:最小24×24 CSS像素
  • 目标之间要有足够的间距(8px以上间隙)

10.2 Touch Behavior

10.2 触摸行为

  • Use
    touch-action: manipulation
    (prevents double-tap zoom delay)
  • Set
    -webkit-tap-highlight-color
    intentionally (or transparent)
  • Use
    overscroll-behavior: contain
    in modals/drawers/sheets
  • 使用
    touch-action: manipulation
    (防止双击缩放延迟)
  • 有意设置
    -webkit-tap-highlight-color
    (或设为透明)
  • 在模态框/抽屉/面板中使用
    overscroll-behavior: contain

10.3 Drag & Drop

10.3 拖放

  • During drag: disable text selection (
    user-select: none
    )
  • Use
    inert
    on dragged elements
  • Provide keyboard alternative for drag operations (WCAG)
  • 拖放期间:禁用文本选择(
    user-select: none
  • 对拖拽元素使用
    inert
  • 为拖放操作提供键盘替代方案(WCAG要求)

10.4 Focus on Mobile

10.4 移动端焦点

  • Use
    autoFocus
    sparingly — desktop only, single primary input
  • Avoid
    autoFocus
    on mobile (may cause viewport jump)

  • 谨慎使用
    autoFocus
    — 仅在桌面端、单个主要输入框使用
  • 避免在移动端使用
    autoFocus
    (可能导致视口跳转)

11. Layout & Safe Areas

11. 布局与安全区域

11.1 Safe Areas

11.1 安全区域

  • Full-bleed layouts need
    env(safe-area-inset-*)
    for notches, home indicators
  • Bottom fixed elements:
    padding-bottom: env(safe-area-inset-bottom)
  • 全屏布局需要使用
    env(safe-area-inset-*)
    适配刘海、Home指示器
  • 底部固定元素:
    padding-bottom: env(safe-area-inset-bottom)

11.2 Overflow Management

11.2 溢出管理

  • Avoid unwanted scrollbars: check for content overflow
  • Use
    overflow-x: hidden
    carefully (only when justified)
  • Prefer Flexbox/Grid over JavaScript measurement for layout
  • 避免不必要的滚动条:检查内容溢出
  • 谨慎使用
    overflow-x: hidden
    (仅在合理时使用)
  • 优先使用Flexbox/Grid而非JavaScript测量来实现布局

11.3 Responsive Design

11.3 响应式设计

  • Mobile-first approach: start with mobile styles, add larger breakpoints
  • Use fluid typography:
    clamp()
    for font sizes
  • Use container queries for component-level responsiveness
  • Test at common breakpoints: 320px, 375px, 768px, 1024px, 1440px

  • 移动优先方法:从移动端样式开始,添加更大的断点
  • 使用流体排版:
    clamp()
    设置字体大小
  • 使用容器查询实现组件级响应式
  • 在常见断点测试:320px、375px、768px、1024px、1440px

12. Dark Mode & Theming

12. 深色模式与主题

12.1 System Integration

12.1 系统集成

  • Use
    color-scheme: dark
    on
    <html>
    for dark themes (fixes scrollbar, inputs, form controls)
  • Match
    <meta name="theme-color">
    to page background
  • Native
    <select>
    : set explicit
    background-color
    and
    color
    (Windows dark mode fix)
  • 深色主题在
    <html>
    上使用
    color-scheme: dark
    (修复滚动条、输入框、表单控件)
  • <meta name="theme-color">
    与页面背景匹配
  • 原生
    <select>
    :明确设置
    background-color
    color
    (修复Windows深色模式问题)

12.2 User Preference

12.2 用户偏好

  • Honor
    prefers-color-scheme
    media query
  • Provide manual toggle that persists preference
  • Ensure all UI elements work in both modes

  • 遵循
    prefers-color-scheme
    媒体查询
  • 提供可保存偏好的手动切换开关
  • 确保所有UI元素在两种模式下都能正常工作

13. Internationalization (i18n)

13. 国际化(i18n)

13.1 Locale-Aware Formatting

13.1 区域感知格式化

  • Dates/times: use
    Intl.DateTimeFormat
    , not hardcoded formats
  • Numbers/currency: use
    Intl.NumberFormat
    , not hardcoded formats
  • Relative time: use
    Intl.RelativeTimeFormat
  • 日期/时间:使用
    Intl.DateTimeFormat
    ,不要硬编码格式
  • 数字/货币:使用
    Intl.NumberFormat
    ,不要硬编码格式
  • 相对时间:使用
    Intl.RelativeTimeFormat

13.2 Language Detection

13.2 语言检测

  • Detect language via
    Accept-Language
    header or
    navigator.languages
  • NEVER use IP geolocation for language detection
  • 通过
    Accept-Language
    头或
    navigator.languages
    检测语言
  • 绝对不要使用IP地理定位检测语言

13.3 RTL Support

13.3 RTL支持

  • Use logical CSS properties:
    margin-inline-start
    not
    margin-left
  • Set
    dir="rtl"
    on
    <html>
    for RTL languages
  • Test layout in RTL mode

  • 使用逻辑CSS属性:
    margin-inline-start
    而非
    margin-left
  • 对RTL语言在
    <html>
    上设置
    dir="rtl"
  • 在RTL模式下测试布局

14. Hydration Safety (SSR/SSG)

14. Hydration安全性(SSR/SSG)

14.1 Controlled Inputs

14.1 受控输入

  • Inputs with
    value
    prop MUST have
    onChange
    handler
  • Or use
    defaultValue
    for uncontrolled inputs
  • 带有
    value
    属性的输入框必须有
    onChange
    处理函数
  • 或对非受控输入使用
    defaultValue

14.2 Client-Only Content

14.2 仅客户端内容

  • Date/time rendering: guard against hydration mismatch (server vs client timezone)
  • Use
    suppressHydrationWarning
    only where truly needed
  • Dynamic content based on
    window
    /
    localStorage
    : render client-side only

  • 日期/时间渲染:防止Hydration不匹配(服务器与客户端时区不同)
  • 仅在真正需要时使用
    suppressHydrationWarning
  • 基于
    window
    /
    localStorage
    的动态内容:仅在客户端渲染

15. Interactive States

15. 交互状态

15.1 Hover & Active States

15.1 悬停与激活状态

  • Buttons and links MUST have
    hover:
    state (visual feedback)
  • Interactive states should increase contrast/prominence
  • Hover → Active → Focus progression should be visually clear
  • 按钮和链接必须有
    hover:
    状态(视觉反馈)
  • 交互状态应提高对比度/突出显示
  • 悬停→激活→焦点的过渡应视觉清晰

15.2 Disabled States

15.2 禁用状态

  • Use
    disabled
    attribute, not just styling
  • Disabled elements: reduced opacity (0.5-0.6),
    cursor: not-allowed
  • Consider
    aria-disabled="true"
    if element should remain focusable

  • 使用
    disabled
    属性,而不仅仅是样式
  • 禁用元素:降低透明度(0.5-0.6),设置
    cursor: not-allowed
  • 如果元素需要保持可聚焦,考虑使用
    aria-disabled="true"

Anti-Patterns Checklist

反模式检查清单

Flag these immediately:
PatternIssue
user-scalable=no
or
maximum-scale=1
Disables zoom — accessibility violation
onPaste
+
preventDefault()
Blocks paste — UX hostile
transition: all
Performance issue — list properties
outline: none
/
outline-none
without focus replacement
Removes focus indicator — accessibility violation
<div onClick>
or
<span onClick>
Should be
<button>
or
<a>
<img>
without
width
/
height
Causes layout shift (CLS)
<img>
without
alt
Missing alt text — accessibility violation
Form inputs without
<label>
Missing label — accessibility violation
Icon buttons without
aria-label
Screen reader can't identify action
Hardcoded date/number formatsShould use
Intl.*
APIs
autoFocus
without clear justification
May cause issues on mobile
Large arrays with
.map()
without virtualization
Performance issue for 50+ items
tabindex
> 0
Disrupts natural tab order
Color-only indicatorsFails colorblind users
Placeholder as labelLabel disappears on input

立即标记以下模式:
模式问题
user-scalable=no
maximum-scale=1
禁用缩放 — 违反可访问性要求
onPaste
+
preventDefault()
阻止粘贴 — 对用户不友好
transition: all
性能问题 — 应列出具体属性
outline: none
/
outline-none
无焦点替代方案
移除焦点指示器 — 违反可访问性要求
<div onClick>
<span onClick>
应使用
<button>
<a>
<img>
width
/
height
属性
导致布局偏移(CLS)
<img>
alt
属性
缺少替代文本 — 违反可访问性要求
表单输入框无
<label>
缺少标签 — 违反可访问性要求
纯图标按钮无
aria-label
屏幕阅读器无法识别操作
硬编码日期/数字格式应使用
Intl.*
APIs
autoFocus
无明确理由
可能在移动端引发问题
大型数组使用
.map()
而不虚拟化
50项以上会有性能问题
tabindex
> 0
打乱自然Tab顺序
仅依赖颜色的指示器色盲用户无法识别
占位符作为标签输入时标签消失

Output Format

输出格式

Group by file. Use
file:line
format (VS Code/IDE clickable). Terse findings.
text
undefined
按文件分组。使用
file:line
格式(VS Code/IDE可点击)。结果简洁。
text
undefined

src/components/Button.tsx

src/components/Button.tsx

src/components/Button.tsx:42 - icon button missing aria-label src/components/Button.tsx:18 - input lacks associated label src/components/Button.tsx:55 - animation missing prefers-reduced-motion check src/components/Button.tsx:67 - transition: all → list specific properties src/components/Button.tsx:89 - div with onClick → use <button>
src/components/Button.tsx:42 - 纯图标按钮缺少aria-label src/components/Button.tsx:18 - 输入框缺少关联标签 src/components/Button.tsx:55 - 动画未检查prefers-reduced-motion src/components/Button.tsx:67 - transition: all → 列出具体属性 src/components/Button.tsx:89 - div使用onClick → 改用<button>

src/components/Modal.tsx

src/components/Modal.tsx

src/components/Modal.tsx:12 - missing overscroll-behavior: contain src/components/Modal.tsx:34 - "..." → use "…" (proper ellipsis) src/components/Modal.tsx:78 - no focus trap for modal dialog
src/components/Modal.tsx:12 - 缺少overscroll-behavior: contain src/components/Modal.tsx:34 - "..." → 使用“…”(正确的省略号) src/components/Modal.tsx:78 - 模态框未设置焦点陷阱

src/components/Card.tsx

src/components/Card.tsx

✓ No issues found
✓ 未发现问题

Summary

总结

  • 8 accessibility issues
  • 3 performance issues
  • 2 UX issues
  • Priority: Fix accessibility issues first (WCAG compliance)

State issue + location. Skip explanation unless fix non-obvious. No preamble.

---
  • 8个可访问性问题
  • 3个性能问题
  • 2个UX问题
  • 优先级:优先修复可访问性问题(符合WCAG标准)

说明问题及位置。除非修复方案不明确,否则跳过解释。不要有开场白。

---

References

参考资料

Related EasyPlatform Docs

相关EasyPlatform文档

  • SCSS Styling Guide - Angular/BEM patterns, platform-specific SCSS conventions
  • Frontend Patterns - Angular component hierarchy, state management
  • SCSS样式指南 - Angular/BEM模式、平台特定SCSS约定
  • 前端模式 - Angular组件层级、状态管理

IMPORTANT Task Planning Notes

重要任务规划说明

  • Always plan and break many small todo tasks
  • Always add a final review todo task to review the works done at the end to find any fix or enhancement needed
  • 始终规划并拆分为多个小的待办任务
  • 始终添加最终审查待办任务,在结束时检查已完成的工作,寻找任何需要修复或改进的地方