想象你刚刚接管了一栋住满各种客人的摩天大厦。有视障的住户需要盲文按钮,色弱的访客分不清红绿指示灯,坐轮椅的业主得靠坡道替代台阶——而你手下的物业团队只有四个人,根本不可能蹲在每层楼梯口逐一检查。这时,你买了一台名叫“小斧”的巡检机器人。它揣着一本厚厚的检查清单,沿着楼层一寸寸扫过,发现盲道被占用就贴橙色标签,应急灯亮度不足就贴黄色标签,下班前交给你一份带照片、带坐标的巡检报告。你只需要照着标签颜色安排工期,修完请它复检一遍。 这篇教程的主角,就是网页世界的“小斧”——axe-core。它把你的页面当作一栋大厦,自动检查按钮有没有名字、图片有没有替代文字、文字颜色和背景对比够不够清楚、无障碍标签有没有被滥用,最后整理成一份结构化的 JSON 报告。读懂这份报告,并把这台机器人排进你的日常巡逻路线——也就是 CI/CD 流水线——你就掌握了前端无障碍(A11y)自动化检测的核心能力。

岗位关联

无障碍合规正成为产品验收与法律法规的硬性要求。掌握 axe-core 自动化检测,等于为团队装上一位 24 小时在线的无障碍巡检员,让隐藏在前端页面里的问题在发布前就现出原形。这是前端工程师、测试工程师与开发者工具团队必备的工程素养。

目录
  1. 可视化演示
  2. A11y检测基础
  3. axe-core原理
  4. 规则体系解析
  5. 常见检测项
  6. 集成工作流
  7. 报告与修复
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示axe-core无障碍检测规则、DOM树遍历、违规严重度分级及CI流水线集成机制,含粒子场背景和发光动画。

本节配有交互动效(进入视口后自动加载,约 3KB)。

A11y检测基础

大厦的坡道不只是给轮椅用的——推婴儿车的妈妈、拖着行李箱的旅客、送货的搬运师傅,全都受益于此。网页也一样。无障碍(A11y)这个词,英文是 Accessibility,取首字母 A、末字母 y、中间 11 个字母,所以缩写成 A11y。它的核心思想是:不论视力、听力、行动力、认知能力如何,所有人都能平等地获取信息和完成任务。

网页世界的“建筑规范”叫做 WCAG——Web 内容无障碍指南,由 W3C 发布。它像一册厚厚的消防条例,规定了文本对比度、键盘可达性、表单可辨识性等标准。问题是,人工对照这册条例逐页检查,就像物业经理拿着 200 页手册亲自爬遍整栋楼的每一层,费时费力还容易遗漏。

axe-core 就是来解决这个痛点的。它是 Deque Systems 开源的自动化无障碍检测引擎,能在毫秒级扫描完一个页面,输出标准化的 JSON 报告。它被公认为业界事实标准,因为规则覆盖面广、误报率低,还深度支持 CI 集成。自动化检测的价值在于“持续且一致”——人会有情绪波动、会有看漏,机器人却永远按同一把尺子量每一页。

一座楼如果坡道、盲道、标识全部合规,每一位访客都会感受到这份用心。同样地,当你的页面通过 axe-core 全量扫描,其实是在向每一位用户传递一个信号:这个产品,欢迎所有人。

coverage=covered_rulestotal_rules×100%\textstyle coverage = \frac{covered\_rules}{total\_rules} \times 100\%
覆盖率表示当前项目里,axe-core 能自动检查的规则占全部规则的比例。它帮你直观评估无障碍检测的“体检完整度”。
  1. covered_rules(已覆盖规则数)你的项目实际触发的、且 axe-core 能够自动判断的规则数量。比如页面上有图片,那么“图片必须带 alt 文本”这条规则就算被覆盖。
  2. total_rules(规则总数)axe-core 内置的全部规则总量,目前超过 90 条。其中包括 WCAG 各级别映射和最佳实践类规则。
  3. × 100%把比值转成百分比,方便团队设定质量门禁阈值,例如“A11y 覆盖率不得低于 80%”。

axe-core原理

小斧是怎么工作的?它不是魔法,而是一个结构清晰的三段式巡检流程:睁眼——看到全楼所有角落;对照——把看到的东西和检查清单比对;贴条——给不合格的地方登记造册。

对应到技术上,axe-core 的执行入口是 axe.run()。它接受三个参数:上下文(你要查哪一栋楼)、选项(要跑哪些规则的配置)、回调函数。调用时,axe-core 会把一个 JavaScript 运行脚本注入到页面里,在浏览器环境中遍历 DOM 树,把所有元素作为候选对象交给规则引擎。

规则引擎是它的“大脑”。每一条规则都由两部分组成:一个 CSS 选择器匹配器(决定这个规则关心哪些元素,比如 img 标签)和一个 JavaScript 检查函数(对匹配到的元素做布尔判定)。当一个元素同时满足“被规则关心”且“检查不通过”时,它就被记录为一个 violations 成员。整个扫描是异步的,返回一个 Promise,结果中包含违规、通过、无法自动判断三类信息。

小斧最让物业团队省心的一点,是它连“房间里的密室”也能进——现代前端组件常把样式封装在影子 DOM 里,就像大厦楼内的隐形隔间。axe-core 对此有专门支持,让阴影中的违规也无所遁形。

violations={  n∈DOM    ∣    rule(n)=false  }\textstyle violations = \{ \; n \in DOM \;\;|\;\; rule(n) = false \; \}
这行集合语言翻译过来是:把所有“让某条规则返回 false 的页面元素 n”收集起来,它们就是违规项。
  1. n(页面元素)DOM 树上的任意一个节点,可能是 <button>、<img> 或 <a> 标签。小斧的眼睛会逐个扫过它们。
  2. ∈ DOM“属于页面文档树”,意思是只在当前网页的范围内巡逻。SPA 切换路由后,DOM 变了,需要重新跑一次。
  3. rule(n) = false某条规则对这个元素“否决”了。好比检查清单上写着“按钮必须有名字”,而这个按钮没有名字,于是被判定违规。

规则体系解析

小斧手里的检查清单不是随手写的,而是有官方依据的“标准手册”。axe-core 内置 90 多条规则,每一条都标注了对应的 WCAG 等级标签:wcag2a、wcag2aa、wcag2aaa,分别对应 A 级、AA 级、AAA 级;还有一类不计入 WCAG 但很实用的规则,叫 best-practice,比如“页面应包含 landmark 区域”。

用 runOnly 可以筛选规则集——比如只跑 wcag2a 和 wcag2aa,满足大多数公司合规验收的要求。每条规则还有自己的 impact 字段,相当于小斧给问题贴的标签颜色:critical(红色,完全不可用)、serious(橙色,严重影响操作)、moderate(黄色,造成困扰)、minor(蓝色,轻微瑕疵)。

这套“颜色标签”体系让团队沟通变得简单:产品经理不需要读懂代码,只需要知道“这周必须把红色和橙色清完”。

impact:    R→{critical,  serious,  moderate,  minor}\textstyle impact: \;\; R \rightarrow \{critical,\; serious,\; moderate,\; minor\}
这是一条从规则映射到严重级别的函数:每个检查项都会被归入四个颜色档位之一,方便你决定先修什么。
  1. R(规则集合)本次扫描被触发的所有规则的集合。比如页面里有图,就会触发 image-alt。
  2. →(映射)每条规则都对应且只对应一个严重级别。就像小斧对每条违规只会贴一种颜色的标签。
  3. {critical, serious, moderate, minor}四个档位从重到轻。critical 意味着某类用户完全无法完成核心任务。

常见检测项

巡检半年后,小斧带回了一份高频问题排行。排在榜首的是三类:颜色对比度不足、图片缺替代文本、按钮没有名字。它们占了全部违规的六成以上,而且修复成本极低。

颜色对比度检测是最有意思的一条。它不只是比较“哪个颜色亮一点”,而是计算两种颜色在真实屏幕上的感知亮度差。WCAG AA 要求普通文本的对比度至少达到 4.5:1,大号文本可以放宽到 3:1。很多设计师选了一个浅灰配白底,肉眼勉强能看,但视力不佳的用户就彻底看不清了。

图片替代文本和按钮名称则是“可访问名称”问题。屏幕阅读器用户看不到图片,全靠 alt 文本描述图片内容;一个只有图标没有文字的按钮,对读屏用户来说就是“无法理解的空白按钮”。axe-core 的 image-alt 和 button-name 规则专门抓这两类问题。

小斧把这三大类问题抓出来之后,真正动手修其实很快:给图片补一句 alt、给按钮加 aria-label、调整调色板里的两三个色值——大厦的“小毛病”大多就是这样十来分钟能解决的事。

C=L1+0.05L2+0.05\textstyle C = \frac{L_{1} + 0.05}{L_{2} + 0.05}
C 是对比度,L₁ 是较亮颜色的相对亮度,L₂ 是较暗颜色的相对亮度。计算要求对比度 C ≥ 4.5 才算符合 WCAG AA。
  1. L₁(较亮色的相对亮度)先分别计算前景色和背景色的感知亮度,亮的那个记为 L₁。白色约等于 1,黑色约等于 0。
  2. L₂(较暗色的相对亮度)亮度较低的那个颜色。如果背景是 #818CF8,前景是 #FFFFFF,就要分别算出两者的亮度值。
  3. + 0.05修正系数,避免纯黑亮度为 0 导致分母为 0 的情况,让公式始终可算。
  4. 比值 ≥ 4.5WCAG AA 对常规字号文本的要求。这个阈值保证了低视力用户能舒服地阅读。

集成工作流

小斧再能干,如果只是每个月手工抱着它爬一次楼,那就少了一半价值。聪明的物业团队会把它的巡检排进每天的晨间例行程序。前端领域也完全一样:把 axe-core 嵌进开发链路,让它在代码提交、集成测试、CI 构建的每个关键节点都自动跑一遍。

最轻量的方式是用官方命令行工具。在项目里安装 @axe-core/cli 后,一条命令就能扫描指定 URL 或 HTML 文件:

--exit 表示发现违规就以非零退出码结束进程,这正是 CI 门禁的基础。更推荐的做法是把它集成到测试框架里:Jest 生态常用 jest-axe,配合 expect(page).toHaveNoViolations() 一条断言;Playwright 和 Cypress 也都有对应的 axe 插件,可以在页面跳转、用户交互之后实时扫描动态内容。

流水线的设计遵循“关键路径优先”原则——不是每张子页面都要全量跑,而是把登录、支付、内容阅读等用户旅程的核心路由列为必检项。CI 阶段一旦发现 critical 或 serious 级违规,直接让构建失败,挡住合并请求。

当小斧的巡检被编进每日晨巡,物业团队再也不用担心“上周漏检的盲道这周有没有人修好”——因为每天早上它都会坚定地重新报告一遍。

CI 通过    ⇔    violationscritical∪violationsserious=∅\textstyle CI \text{ 通过} \;\; \Leftrightarrow \;\; violations_{critical} \cup violations_{serious} = \varnothing
这条公式是 CI 门禁的判定逻辑:只有“红色”和“橙色”问题的并集为空,流水线才允许通过。
  1. ∪(并集)把红色问题清单和橙色问题清单合并成一张总表。物业团队最关心这两类。
  2. = ∅(空集)合并之后一张标签都没有,说明高优先级问题为零,大厦可以继续营业。
  3. ⇔(当且仅当)左边成立右边必成立,右边成立左边也必成立。也就是“门禁是否通过”和“高危及严重违规是否清零”完全等价。
bash1 行
npx @axe-core/cli http://localhost:3000 --exit

报告与修复

小斧交回的巡检报告,是一份结构严谨的 JSON 文档。读懂它,是修复工作的第一步。报告的顶级字段有三个:violations(违规项)、passes(通过项)、incomplete(无法自动判断项)。很多人只看 violations,但 incomplete 同样重要——它相当于是小斧在报告里写的“这块我判断不了,请人工来确认一下”。

每个 violation 对象里包含若干个 nodes,每个 node 指明了具体的 DOM 目标、影响描述和修复建议。有了这些坐标,开发人员不需要费劲猜测“到底哪张图缺 alt 文本”,直接定位即可。

修复顺序不应该平均用力。推荐的做法是给每个违规计算一个优先级:严重级别越高的权重越大,影响的节点数越多越优先。先把红色和橙色清零,再处理黄色,最后有精力时优化蓝色。修复完成一轮后,把小斧重新拉出来跑一遍,确认问题不再复发——这就是“复检闭环”。

小斧把一栋楼的问题整理成了可执行的工单队列。物业团队只要照着优先级列表逐项销号,复检后把报告贴进团队文档,整个项目的无障碍水位就能稳步上升。

P(rule)=weight(impact)×count(nodes)\textstyle P(rule) = weight(impact) \times count(nodes)
P 表示某条规则的修复优先级,等于它的严重级别权重乘以受影响节点数。数值越大,越应该排期提前修。
  1. weight(impact)(严重级别权重)critical=4、serious=3、moderate=2、minor=1。红色问题权重最高,必须第一个处理。
  2. count(nodes)(受影响节点数)报告里这条规则命中多少个页面元素。影响面越广,越该优先。
  3. ×(相乘)两个维度综合打分。一条影响 5 个节点的 serious(3×5=15)会比影响 8 个节点的 moderate(2×8=16)直觉上排在后面,这正是量化排序的好处。

AI 应用场景

CI/CD 无障碍质量门禁

阶段:持续集成与质量保障

解决的问题:传统无障碍检查靠人工抽检,版本迭代后新页面经常漏检;人工复测成本高、标准不统一。axe-core 接入 CI 后,每次提交代码都会自动扫描关键页面,critical 和 serious 级问题直接让构建失败,把问题拦截在合并之前。

具体案例:某电商团队在 GitHub Actions 中配置了 axe 扫描步骤,对登录、购物车、结算三个核心路由跑 wcag2a 和 wcag2aa 规则。一次改版中,按钮的 hover 样式对比度降到 3.2:1,流水线立刻变红,开发者在合并前就完成了修复。

组件库无障碍守护

阶段:开发环境实时反馈

解决的问题:设计系统中的每个组件都可能被复用数百次,组件级别的一个无障碍缺陷会被放大到整个产品线。传统方式是在组件发布后靠用户投诉才发现问题,成本很高。

具体案例:某公司的 Design System 团队在 Storybook 中接入 axe-playwright,给每个组件 story 自动跑无障碍检测。新提交的“下拉选择器”被检测出无法用键盘展开,提交被阻塞,组件库的每个组件从出生起就自带无障碍体检报告。

无障碍报告智能解读

阶段:报告生成与辅助决策

解决的问题:axe-core 输出的 JSON 报告包含大量技术字段,非无障碍方向的开发者阅读门槛高。结合 AI 工具把报告翻译成通俗的自然语言摘要,可大幅降低团队的学习成本。

具体案例:测试团队将 axe 扫描结果输入大模型,生成“这轮迭代新增了 3 个色觉障碍高风险点,分布在首页促销横幅”这样的摘要,同时附上修复代码片段建议,产品经理和技术负责人一眼就能看懂风险。

Python 演示

python82 行
# -*- coding: utf-8 -*-"""axe-core 违规报告解读器:提取并按优先级排序无障碍问题。"""import jsonimport sys SEVERITY_WEIGHT = {    "critical": 4,    "serious": 3,    "moderate": 2,    "minor": 1,} DEMO_REPORT = {    "violations": [        {            "id": "color-contrast",            "impact": "serious",            "help": "确保文本与背景对比度至少 4.5:1",            "nodes": [{"target": ".btn-primary"}, {"target": ".nav-link"}],        },        {            "id": "image-alt",            "impact": "critical",            "help": "为信息型图片提供 alt 替代文本",            "nodes": [{"target": "img.hero"}],        },        {            "id": "button-name",            "impact": "serious",            "help": "按钮元素需要可访问名称",            "nodes": [{"target": "button.icon-close"}],        },        {            "id": "region",            "impact": "moderate",            "help": "页面需要 landmark 区域便于读屏导航",            "nodes": [{"target": "html"}],        },    ]}  def load_report(path):    """读取 axe-core 输出的 JSON 报告;未传路径时使用演示数据。"""    if path is None:        return DEMO_REPORT    with open(path, "r", encoding="utf-8") as f:        return json.load(f)  def summarize(report):    """按 impact 权重降序汇总 violations。"""    items = []    for violation in report.get("violations", []):        items.append({            "rule": violation["id"],            "impact": violation.get("impact", "minor"),            "count": len(violation.get("nodes", [])),            "help": violation.get("help", ""),        })    items.sort(key=lambda x: SEVERITY_WEIGHT.get(x["impact"], 0), reverse=True)    return items  def render(items, top_n=5):    """打印修复优先级清单。"""    print("===== axe-core 修复优先级清单 =====")    for idx, item in enumerate(items[:top_n], 1):        print("{0}. [{1}] 影响 {2} 个节点: {3}".format(            idx, item["impact"], item["count"], item["rule"]))        print("   建议: " + item["help"])  def main():    path = sys.argv[1] if len(sys.argv) > 1 else None    report = load_report(path)    items = summarize(report)    render(items)  if __name__ == "__main__":    main()
目的:把 axe-core 生成的 JSON 违规报告转换成一张按严重级别排序的修复工单,命令行传参支持真实报告文件,不传参则运行内置演示数据。
  1. SEVERITY_WEIGHT = {...}为四个 impact 档位分配权重分,critical 最高 4 分,这是排序的依据。
  2. def load_report(path):兼容两种数据源:传入文件路径读真实报告,否则使用内置演示报告。
  3. report.get("violations", [])安全取值:报告里没有这个键时返回空列表,避免 KeyError。
  4. len(violation.get("nodes", []))统计每条规则影响了多少个节点,用于衡量影响范围。
  5. items.sort(key=lambda x: SEVERITY_WEIGHT.get(...))按权重降序排列,权重最高的红色问题排最前面。
  6. if __name__ == "__main__":保证脚本既能作为模块被导入,也能被命令行直接执行。

常见误区

误区既然 axe-core 跑了没有报错,我们的网站应该完全无障碍了吧?评论区都说这个工具很权威,应该可以放心上线了。

正解axe-core 只能自动覆盖约 30%-40% 的 WCAG 检查点。它擅长检测“结构性、可判定”的问题(缺 alt、对比度不足),但无法判断键盘焦点顺序是否合理、屏幕阅读器的实际朗读体验是否顺畅。自动化扫描通过,只代表机器的检查清单过了,人工测试环节仍然不可省略。

为何常见:工具给出的“绿色通过”给了人很强的确定感,加上很多团队没有专职无障碍测试人员,容易把机器报告当作唯一权威。

误区这个灰色文字和白色背景看着挺清楚的,比旁边那个红色差点,但应该到不了 4.5 也差不多 4 了吧?设计师看着明显就行。

正解对比度不是“看起来像不像”,而是基于颜色相对亮度 L 的精确公式计算。公式里还要考虑透明度混合后的实际渲染颜色。看着清楚的浅灰色在公式里可能只有 2.8:1,远不达标,特别是在强光下或视力不佳场景。

为何常见:人对颜色的感知是相对的、主观的,尤其在明亮屏幕上会对低对比度产生“还行”的错觉。

误区我写了个自动化脚本,打开首页跑一遍 axe-core,结果全绿,那这个应用无障碍没问题。后面路由跳转、弹窗打开我看也差不多。

正解现代 SPA 是动态的——路由切换会重新挂载 DOM,弹窗、表单校验、无限滚动都会产生新的内容。axe 只在“当前可见 DOM”上工作,所以必须在关键交互和路由状态上多次扫描,才能覆盖用户真实走过的路径。

为何常见:习惯性地把网页理解成静态 HTML 文档,忽略了前端框架带来的运行时 DOM 变化。

误区报告里 passes 列出了 40 多条规则,说明这些规则我们都完美通过了,可以卸载了这个环节了。

正解passes 只表示“本次扫描中,这条规则没有发现违规”——它可能是真的合规,也可能是页面上没有该规则关心的元素(比如页面没有视频,video-caption 规则就无事可做)。更需要注意的是 incomplete,它代表工具无法自动判断,需要人工确认。

为何常见:报告的字段名给了人“已通过”的直觉,忽略了 passes 的底层含义是“没抓到问题”而非“确认没有问题”。

误区A11y 修复嘛,就是一个一个给 img 补 alt 文本。把违规列表里 alt 相关的清完,剩下视觉上的问题设计师调调色就行了。

正解alt 只是众多规则中的一条。按钮的可访问名称、ARIA 属性的正确用法、表单标签的关联、语义化地标区域、键盘可达性,都是 axe-core 的检测范围,更不用说它管不到的人工测试项。把 A11y 等同于加 alt,就像把大楼安全等同于检查灭火器。

为何常见:网上关于无障碍的入门文章大多拿“给图片加 alt”做例子,导致不少开发者形成“这就是全部”的刻板印象。

面试题

Q1. axe-core 的核心功能是什么?

单选题 · easy

  • A.网页性能优化工具
  • B.浏览器兼容性检测库
  • C.前端代码语法检查器
  • D.前端无障碍自动化检测引擎← 正确答案

答案:D。axe-core 是 Deque Systems 开源的 A11y 检测引擎,扫描 DOM 后输出违规报告。它不做性能分析(排除 A)、不做浏览器兼容判断(排除 B)、也不是语法检查器(排除 C)。

Q2. WCAG 2.1 AA 级对常规文本对比度的最低要求是多少?

单选题 · easy

  • A.3:1
  • B.4.5:1← 正确答案
  • C.7:1
  • D.2:1

答案:B。WCAG AA 要求常规文本对比度不低于 4.5:1。3:1 是大号文本的阈值,7:1 是 AAA 级要求,2:1 不满足任何 WCAG 文本标准。

Q3. axe-core 报告的 violations 数组中,nodes 字段存放的是什么?

单选题 · easy

  • A.违反规则的 DOM 节点← 正确答案
  • B.规则的完整源码
  • C.规则匹配成功的节点数
  • D.页面的加载时间

答案:A。nodes 列出具体违规的页面元素及其 target 定位和影响描述,帮助开发者直接定位修复,而非规则源码(排除 B)、统计数量(排除 C)或性能数据(排除 D)。

Q4. 在 CI/CD 流水线中集成 axe-core 时,最合理的做法是?

单选题 · mid

  • A.仅在本地开发环境手动运行
  • B.在 CI 中扫描但失败不阻塞
  • C.在关键路由和组件测试里自动扫描← 正确答案
  • D.只在发布前由 QA 手动跑一次

答案:C。正确做法是在核心用户旅程和组件测试中自动扫描,并用失败门禁阻塞合并。本地手跑(A)和 QA 手动(D)无法持续保障;扫描失败不阻塞(B)会让门禁形同虚设。

Q5. axe-core 中 color-contrast 规则的默认 impact 通常属于哪一级?

单选题 · mid

  • A.critical
  • B.serious← 正确答案
  • C.moderate
  • D.minor

答案:B。color-contrast 默认标记为 serious,因为低对比度严重影响阅读能力但页面仍可操作。critical 一般留给“完全无法完成任务”的问题,例如无名称的按钮被读屏完全忽略。

Q6. 关于 axe 报告中的 incomplete 状态,正确的理解是?

单选题 · mid

  • A.表示检测失败需要重跑
  • B.表示可能存在问题需人工确认← 正确答案
  • C.表示页面有暗影 DOM 无法扫描
  • D.表示该规则严重级别过低被忽略

答案:B。incomplete 表示自动化工具无法做出确定判断,需要人工介入确认。它不是执行错误(排除 A),也不仅是 shadow DOM 的问题(排除 C),更不是被忽略(排除 D)。

Q7. 在 axe-core 的 run 配置中,通过什么参数可以只执行指定规则的检测?

单选题 · hard

  • A.runOnly← 正确答案
  • B.excludeRules
  • C.skip
  • D.ignoreTags

答案:A。runOnly 接受 { type: 'rule', values: [...] } 或 tag 列表来限定执行范围。excludeRules、skip、ignoreTags 都不是 axe-core 的合法 API,属于干扰项。

Q8. jest-axe 的 toHaveNoViolations 断言失败时,错误信息主要来自报告中的哪个字段?

单选题 · hard

  • A.passes 数组的条目数
  • B.violations 数组的元素← 正确答案
  • C.incomplete 数组的内容
  • D.url 字段的赋值

答案:B。断言的作用是“不允许存在任何违反项”,一旦发现 violations 有内容就抛出失败。passes(A)和 incomplete(C)都不触发失败,url(D)只是报告元信息。

Q9. 下列哪些是无障碍检测中需要人工辅助判断的问题?

多选题 · mid

  • A.键盘焦点顺序的合理性← 正确答案
  • B.图片标签缺少 alt 属性
  • C.屏幕阅读器朗读的实际语义← 正确答案
  • D.文字颜色对比度数值不达标

答案:AC。焦点顺序和朗读语义依赖真实使用场景中的交互体验,自动化工具很难判定。缺少 alt(B)和对比度不足(D)都是 axe-core 能稳定自动捕获的结构性问题。

Q10. 关于 axe-core 在动态渲染页面(SPA)中的使用,正确的说法是?

多选题 · extreme

  • A.页面加载完成后只静态扫描一次即可
  • B.路由切换后需重新扫描新挂载的内容← 正确答案
  • C.异步数据渲染结束后再触发扫描更准确← 正确答案
  • D.shadow DOM 内部元素无法被 axe-core 检测

答案:BC。SPA 的路由切换会重建 DOM,必须在关键状态重新扫描(B);异步渲染需等待数据挂载完成后再扫,否则会漏检(C)。只扫一次(A)会错过动态内容;shadow DOM 内元素 axe-core 是可以检测的,D 错误。