Skip to content

参考

基于 Nielsen Norman Group、W3C WAI WCAG 2.2 Understanding、web.dev、MDN、TanStack Query v5 官方文档编写,对照 2026-07 现状

速查

  • NN/g 三档响应时间:0.1s 瞬时 / 1s 思路不中断 / 10s 注意力上限需进度条
  • CLS 阈值:≤ 0.1(良好)/ 0.1–0.25(需改善)/ > 0.25(差),无单位分数
  • 触摸目标 WCAG:2.5.8 AA 24×24 CSS px / 2.5.5 AAA 44×44 CSS px
  • 错误三阶梯:3.3.1 (A) 识别 / 3.3.3 (AA) 修正建议 / 3.3.4 (AA) 法律财务类三选一
  • WCAG 1.3.5:H98 用 autocomplete 标准 token;F107 = autocomplete 值不合法
  • ARIA Liverole="alert" = aria-live="assertive"(紧急错误);普通用 polite
  • 乐观更新三回调链onMutateonErroronSettled,缺一不可
  • WCAG 2.2:2023-10-05 正式推荐标准,新增 2.5.8 Target Size (Minimum)
  • React 19:2024-12 稳定,useOptimistic 原生支持乐观 UI
  • TanStack Query v5onMutateonErroronSettled 回滚范式为事实标准
  • 现代浏览器:Chrome 79+ / Firefox 71+ / Safari 14+ 根据 <img> 的 width/height 自动算 aspect-ratio

WCAG 准则速查表

准则等级名称核心要求技术 / 失败
2.5.8AATarget Size (Minimum)指针输入目标 ≥ 24×24 CSS px5 例外:Spacing / Equivalent / Inline / User Agent Control / Essential
2.5.5AAATarget Size (Enhanced)指针输入目标 ≥ 44×44 CSS px4 例外:Equivalent / Inline / User Agent Control / Essential;技术 C44
1.3.5AAIdentify Input Purpose用 HTML autocomplete 标准 token 标识输入用途H98(实现)/ F107(失败:值不合法)
3.3.1AError Identification自动检测的错误以文本告知用户不能只靠颜色 / 图标
3.3.3AAError Suggestion识别错误并给可操作的修正建议不只说「错误」「无效」
3.3.4AAError Prevention(Legal/Financial/Data)法律 / 财务 / 删数据类操作三选一可撤销 / 检查错误给修正 / 提交前确认
1.1.1ANon-text Content所有非文本内容提供 alt 等文本替代inline img 无 alt 即违反
1.4.13AAContent on Hover or Focushover / focus 弹出层可关闭 / 可悬停 / 持久tooltip、菜单弹出层

WCAG 2.2 于 2023-10-05 成为 W3C 正式推荐标准(Recommendation),新增 2.5.8 Target Size (Minimum) AA;2.5.5 Target Size (Enhanced) 自 WCAG 2.1 (2018) 起即为 AAA。

NN/g 响应时间表

等待时长用户感知反馈方式例子
< 0.1s瞬时、直接操控感无需反馈(感官上因果连为一体)按钮按下、checkbox 勾选
0.1s – 1s思路不中断,可察觉延迟可略延迟,需要轻量 spinner 提示局部刷新、tab 切换
1s – 10s思路被打断,注意力流失spinner / 骨架屏明确反馈表单提交、列表加载
> 10s注意力上限,焦虑想离开必须 percent-done 进度条 + 可中断大文件上传、复杂分析

反馈类型选型表

加载时长推荐反馈原因
< 1s不放反馈闪一下是负优化(NN/g)
2–10s骨架屏 或 spinner骨架屏适合整页(暗示结构 + 防 CLS);spinner 适合单个模块
> 10s必须用进度条(percent-done)长等待需明确进度 + 可中断

触摸目标速查表

WCAG 2.5.8 Target Size (Minimum) AA

取值
最低尺寸24×24 CSS px
例外数5 个
例外名Spacing / Equivalent / Inline / User Agent Control / Essential
Spacing 判定目标边界框中心画 24px 直径圆与其他目标圆不相交
引入版本WCAG 2.2(2023-10-05)

WCAG 2.5.5 Target Size (Enhanced) AAA

取值
最低尺寸44×44 CSS px
例外数4 个
例外名Equivalent / Inline / User Agent Control / Essential(无 Spacing
推荐技术C44(min-width + min-height
引入版本WCAG 2.1(2018)

事实标准参考

来源推荐尺寸
WCAG 2.5.8 AA(底线)24×24 CSS px
WCAG 2.5.5 AAA(增强)44×44 CSS px
Apple HIG44 pt
Google Material48 dp

CLS 速查表

取值
良好(Good)≤ 0.1(需覆盖 ≥75% 访问)
需改善(Needs Improvement)0.1 – 0.25
差(Poor)> 0.25
单位无单位分数(区别于 LCP/INP 的毫秒)
计算公式影响比例 × 距离比例
500ms 宽限规则用户交互后 500ms 内的位移不计入 CLS
滚动后位移算入 CLS(无宽限)

CLS 成因与对策

成因对策
图片 / iframe / video 无尺寸HTML 写 width + height(浏览器自动算 aspect-ratio)
字体加载(FOIT/FOUT)font-display: optionalpreload 字体(归性能章)
动态注入内容min-height / aspect-ratio 占位
广告位 / 嵌入预留 min-height不要无广告时收回
SSR hydration 二次插入服务端 / 客户端渲染结果对齐

ARIA Live 用法表

属性 / 角色行为用途
aria-live="off"不播报不重要的动态内容
aria-live="polite"当前任务结束才播报普通内联验证、内容就绪、空状态变化
aria-live="assertive"立即打断当前任务紧急错误、必须立即通知
role="alert"等同 aria-live="assertive"仅紧急错误;多个并存是反模式
aria-atomic="true"整个区域内容变化都重新播报播报完整性优先
aria-atomic="false"(默认)只播报变化部分节省语音
aria-relevant="additions removals text"决定哪些变化触发播报默认 additions text
aria-busy="true"容器正在加载 / 修改,内容就绪后再暴露骨架屏容器、乐观更新表单

ARIA19 结论:role="alert" 等价 aria-live="assertive",仅用于紧急错误;普通内联验证用 aria-live="polite";多个 assertive 区域并存是反模式。

乐观更新三回调链速查(TanStack Query v5)

回调触发时机职责
onMutatemutation 触发前cancelQueries 取消在飞查询
getQueryData 存快照
setQueryData 写乐观值
return { previousData } 传给 onError
onErrormutation 失败setQueryData(context.previousData) 回滚
onSettled成功或失败都触发invalidateQueries 与服务端对齐
缺哪步后果
cancelQueries后台 refetch 旧数据覆盖乐观值 → UI 闪烁
不存快照失败时无法回滚 → UI 停留在「成功」假象
invalidateQueriesUI 与后端持久不一致

React 19 useOptimistic(2024-12 稳定):

ts
const [optimisticState, addOptimistic] = useOptimistic(
  state,
  (currentState, newValue) => /* 返回新状态 */
);

表单 autocomplete 标准 token 速查

由 WHATWG HTML Living Standard 维护,WCAG 1.3.5 (AA) 引用之(技术 H98)。

场景token
姓名name / given-name / additional-name / family-name
联系email / tel / tel-country-code / street-address / address-line1
账号username / current-password / new-password
生日bday / bday-day / bday-month / bday-year
性别sex
支付cc-name / cc-number / cc-exp / cc-exp-month / cc-exp-year / cc-csc
一次性one-time-code

type="email" 不满足 1.3.5——「email」太粗,不区分本人邮箱还是他人邮箱。

浏览器与框架支持现状(2026-07)

特性状态
<img width> + <height> 自动算 aspect-ratioChrome 79+ / Firefox 71+ / Safari 14+,Baseline
prefers-reduced-motion 媒体查询Media Queries Level 5,主流浏览器稳定(Safari 10.1+ / Chrome 74+ / Firefox 63+)
WCAG 2.22023-10-05 W3C 正式推荐标准(含 2.5.8)
Core Web VitalsLCP / INP / CLS(2024-03-12 INP 取代 FID)
React 19 useOptimistic2024-12 稳定
TanStack Query v5onMutateonErroronSettled 事实标准
HTML autocomplete 标准 tokenWHATWG HTML Living Standard 维护

反模式清单(一图速查)

反模式后果 / 违规项
Frame-display 骨架屏(只画 header/footer)等价 spinner,用户等久了判定页面无响应
cancelQueries 直接 setQueryData后台 refetch 覆盖乐观值,UI 闪烁
多个 aria-live="assertive" 并存读屏互相打断、播报混乱
表单错误只说「错误」「无效」违反 3.3.1 和 3.3.3
移除广告位预留 min-height移除预留本身造成 CLS
<img> 不写 width/height加载完成撑开布局 → CLS
onChange 每次按键报错用户尚未输完被错误淹没,放弃率上升
触摸目标 16×16 / 20×20 无间距24px 圆相交,违反 2.5.8 (AA)
裸「No data」/ 空白页空状态用户无法判断是出错还是真没数据
opacity 闪烁代替骨架屏内容占位对 prefers-reduced-motion 用户是生理伤害
乐观更新不 invalidateQueriesUI 与后端持久不一致
<img>alt 又无尺寸CLS 源头 + 违反 1.1.1

官方资源

Nielsen Norman Group

W3C WAI WCAG 2.2

web.dev / MDN

框架官方

GitHub