@a11y-oracle/focus-analyzer

中文文档
1.3.2发布于 2026/03/12MITTypeScriptES Module近 30 天下载 6255

焦点指标 CSS 分析(WCAG 2.4.12),制表指令提取和键盘陷阱检测

中文使用文档
文档目录8 节
  1. 安装
  2. 使用量
  3. API 参考
  4. FocusAnalyzer
  5. 纯公用函数
  6. 类型
  7. 出口
  8. 限制

@a11y-oracle/焦点分析器

无障碍测试的重点状态分析. 提供视觉焦点指标检查,WCAG对比比计算,DOM制取分页指令,以及键盘陷阱检测.

这是内部使用的低层构件 @a11y-oracle/core-engine。大多数用户应该使用 Playwright 或 Cypress 插件.

安装

npm install @a11y-oracle/focus-analyzer

使用量

import { FocusAnalyzer } from '@a11y-oracle/focus-analyzer';

const analyzer = new FocusAnalyzer(cdpSession);

// Analyze the focus indicator on the currently focused element
const indicator = await analyzer.getFocusIndicator();
console.log(indicator.isVisible);     // true
console.log(indicator.contrastRatio); // 12.63
console.log(indicator.meetsWCAG_AA);  // true (visible + contrast >= 3.0)
console.log(indicator.outlineColor);  // "rgb(0, 95, 204)"
console.log(indicator.outlineWidth);  // "3px"

// Extract all tabbable elements in DOM tab order
const entries = await analyzer.getTabOrder();
entries.forEach(e => {
  console.log(`${e.index}: ${e.tag}#${e.id} (tabIndex=${e.tabIndex})`);
});

// Detect keyboard traps (WCAG 2.1.2)
const result = await analyzer.detectKeyboardTrap('#modal-container', 20);
if (result.isTrapped) {
  console.log('Focus is trapped!');
} else {
  console.log(`Focus escaped to: ${result.escapeElement?.tag}`);
}

API 参考

FocusAnalyzer

constructor(cdp: CDPSessionLike)

创建一个新的焦点分析器 。 内部创建 a KeyboardEngine 用于探测陷阱.

  • cdp - 任何 CDP 兼容的会话(使用 CDPSessionLike 界面从 @a11y-oracle/cdp-types) (中文(简体) ).

getFocusIndicator(): Promise<FocusIndicator>

分析当前焦点元素的视觉焦点指标.

提取计算 CSS 属性(outline, (中文(简体) ), box-shadow, (中文(简体) ), border-color, (中文(简体) ), background-color)通过 Runtime.evaluate,然后对照背景计算焦点指标的对比率.

如果没有元素焦点,则返回默认的“不可见”指标.

可见度检测 :

  • 元素有可见 大纲 若为 outline-width 没有 0px 和轮廓颜色有一个非零的α通道(探测两个 transparent 关键词和 rgba(0, 0, 0, 0) 其 Chrome 报告为透明大纲)
  • 元素有可见 框阴影 若为 box-shadow 没有 none

对比计算 :

  • 大纲:对比比 outline-color 财务报告和审定财务报表 background-color
  • 对于框阴影:取出所有颜色 box-shadow 值,过滤出透明值,并使用 最外向可见的颜色 (最后不透明)用于对比计算。 这样可以正确处理Tailwind CSS多环模式,其中装饰的空间器环会先出现而实际的焦点指示环会后出现.
  • 回返 contrastRatio: null 如果颜色不能可靠地解析(例如梯度、复杂的颜色函数)

2.4.12 AA 遵守情况: meetsWCAG_AA 实值 true 当指标可见,而对比比为 QQ 3.0.

getTabOrder(): Promise<TabOrderEntry[]>

按标签顺序从 DOM 中提取所有可制表元素 .

可聚焦要素的查询(a[href], (中文(简体) ), button:not([disabled]), (中文(简体) ), input:not([disabled]), (中文(简体) ), select:not([disabled]), (中文(简体) ), textarea:not([disabled]), (中文(简体) ), [tabindex],然后过滤出 :

  • 要件 tabIndex < 0
  • 隐藏元素( E)display: none, (中文(简体) ), visibility: hidden(中文(简体) )
  • 无布局的元素( N)offsetParent === null(中文(简体) )
  • 内部要素 [inert] 集装箱

结果按 tabIndex 数值:正数 tabIndex 数值首先(升起),然后 tabIndex=0 dOM 顺序中的元素.

detectKeyboardTrap(selector: string, maxTabs?: number): Promise<TraversalResult>

检测焦点是否被困在容器内(WCAG 2.1.2).

  1. 将第一个可制表元素放在容器匹配中 selector
  2. 多次按下标签(最多 maxTabs,默认为50)
  3. 每个标签后检查焦点是否离开了容器
  4. 如果焦点脱逃,立即返回,或者如果 maxTabs 已经用尽

回返 { isTrapped: false, tabCount: 0 } 如果容器不存在或没有可聚焦元素.

纯公用函数

软件包还输出纯函数用于色彩解析和WCAG对比计算:

parseColor(css: string): RGBColor | null

将 CSS 颜色字符串分析为 RGBColor 对象。 支持 :

  • rgb(r, g, b) 财务报告和审定财务报表 rgba(r, g, b, a)
  • 十六进制颜色 : #RGB, (中文(简体) ), #RRGGBB, (中文(简体) ), #RRGGBBAA
  • transparent (回报) { r: 0, g: 0, b: 0, a: 0 }(中文(简体) )

回返 null 用于不支持的格式(名称颜色, hsl(), (中文(简体) ), color()(见a/c.5/49/70,附件).

srgbToLinear(channel: number): number

将 sRGB 通道值 (0-255) 转换为线性光.

relativeLuminance(color: RGBColor): number

计算 WCAG 相对亮度 : L = 0.2126*R + 0.7152*G + 0.0722*B

contrastRatio(color1: RGBColor, color2: RGBColor): number

计算两种颜色之间的WCAG对比比。 返回1(相同)至21(白色黑)之间的值.

meetsAA(ratio: number): boolean

请检查archive-date=中的日期值 (帮助) WCAG AA对焦指标的对比率是否与 WCAG AA相符合(QQ 3.0).

类型

RGBColor

interface RGBColor {
  r: number; // 0-255
  g: number; // 0-255
  b: number; // 0-255
  a: number; // 0-1
}

FocusIndicator

全面重点指标分析:

interface FocusIndicator {
  isVisible: boolean;
  outline: string;          // Raw outline shorthand
  outlineColor: string;     // e.g. "rgb(0, 95, 204)"
  outlineWidth: string;     // e.g. "3px"
  outlineOffset: string;    // e.g. "0px"
  boxShadow: string;        // e.g. "0px 0px 0px 3px rgb(52, 152, 219)"
  borderColor: string;
  backgroundColor: string;
  contrastRatio: number | null;
  meetsWCAG_AA: boolean;
}

TabOrderEntry

interface TabOrderEntry {
  index: number;     // Position in tab order (0-based)
  tag: string;       // "BUTTON"
  id: string;
  textContent: string;
  tabIndex: number;
  role: string;
  rect: { x: number; y: number; width: number; height: number };
}

TabOrderReport

interface TabOrderReport {
  entries: TabOrderEntry[];
  totalCount: number;
}

TraversalResult

interface TraversalResult {
  isTrapped: boolean;                  // true if focus never escaped
  tabCount: number;                    // Total Tab presses attempted
  visitedElements: TabOrderEntry[];    // Elements that received focus
  escapeElement: TabOrderEntry | null; // First element outside container
}

出口

export { FocusAnalyzer } from '@a11y-oracle/focus-analyzer';
export { parseColor } from '@a11y-oracle/focus-analyzer';
export { srgbToLinear, relativeLuminance, contrastRatio, meetsAA } from '@a11y-oracle/focus-analyzer';
export type { RGBColor, FocusIndicator, TabOrderEntry, TraversalResult, TabOrderReport } from '@a11y-oracle/focus-analyzer';

限制

  • 复杂的重点指标 - 梯级,CSS color-mix(),其它高级色彩函数返回 contrastRatio: null 因为它们无法可靠地解析成单一的颜色值.
  • 键盘陷阱检测 ——仅用 Tab 键进行测试. 故意聚焦陷阱(如模式对话框)应当与"逃生"键导航单独测试.
  • tabIndex 命令 ——制表命令提取遵循了标准算法(正数) tabIndex 先说 tabIndex=0 在DOM顺序中),但不计入Shadow DOM边界.

版本与发布记录

@a11y-oracle/focus-analyzer 共发布 10 个版本,首次发布于 2026/03/05;过去 12 个月发布了 10 个版本。

版本发布日期距今
1.3.2latest2026/03/127 个月前
1.3.12026/03/117 个月前
1.3.02026/03/068 个月前
1.2.02026/03/068 个月前
1.1.42026/03/068 个月前
1.1.32026/03/068 个月前

关于 @a11y-oracle/focus-analyzer 的常见问题

@a11y-oracle/focus-analyzer 是什么?

焦点指标 CSS 分析(WCAG 2.4.12),制表指令提取和键盘陷阱检测

如何安装 @a11y-oracle/focus-analyzer?

在项目目录运行 npm install @a11y-oracle/focus-analyzer,或使用 pnpm add / yarn add / bun add。

@a11y-oracle/focus-analyzer 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@a11y-oracle/focus-analyzer 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@a11y-oracle/focus-analyzer 可以商用吗?

@a11y-oracle/focus-analyzer 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@a11y-oracle/focus-analyzer 的下载量有多少?

根据 npm 官方下载统计,@a11y-oracle/focus-analyzer 在 2026/10/05 – 2026/11/03 这 30 天内被下载 6,255 次,日均约 209 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@a11y-oracle/focus-analyzer 还在维护吗?

最新版本 1.3.2 发布于 2026/03/12(7 个月前);至今共发布 10 个版本,其中过去 12 个月发布了 10 个;首次发布于 2026/03/05。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。