Your alt text passes automated checks. That doesn’t mean it’s any good.
TL;DR · AI 摘要
当前网页图像的alt文本存在大量缺失或低质量问题,GitHub推出新插件通过五条规则提升alt文本质量。
核心要点
- 2%的网页图像缺失alt文本,10.8%的alt文本不具描述性
- GitHub插件采用5条确定性规则检查alt文本质量
- Playwright的基于角色的定位器提升图像评估准确性
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- Alt文本质量改进
- 问题现状
- WebAIM报告数据
- 常见低质量类型
- GitHub解决方案
- 五条确定性规则
- AI辅助检查
- 实施方法
- Playwright定位器
- 插件集成
金句 / Highlights
值得收藏与分享的关键句。
WebAIM报告发现16.2%的图像缺失alt文本,10.8%的alt文本不具描述性
GitHub插件采用5条确定性规则,无需AI即可检测低质量alt文本
使用Playwright的基于角色的定位器替代querySelectorAll('img')提升准确性
全球最受欢迎的主页中,超过四分之一的图片缺少替代文本,或描述模糊,甚至直接复制相邻图片的文本。
这是来自WebAIM的2026年WebAIM百万项目报告的数据,该报告显示,在全球排名前100万的主页中,16.2%的图片缺失替代文本属性。在存在替代文本的图片中,另有10.8%的描述不具信息量,例如使用alt="image"、原始文件名或直接复制相邻图片的描述。
虽然自动化工具能可靠地检测缺失的替代文本,但对质量不佳的替代文本改进能力有限。大多数替代文本检查工具仅验证图片是否有可访问名称,而非判断提供的替代文本是否对相关图片有实际描述价值,这是有意为之的设计选择:以质量为导向的规则若存在误报,团队通常会选择关闭。因此alt="IMG_2847.png"会被视为通过检查,同样,五个不同星形图标上重复的alt="3/5 stars"也能通过验证。
我们为GitHub无障碍扫描器开发了替代文本插件,帮助改进替代文本质量。本文将探讨检查器能证明的事实与只能推测的边界,解释我们最严重的漏洞实际上是布局问题而非解析错误,以及引入模型后发生的变化。
如果你正在构建自己的自动化检查工具(无论是否用于无障碍领域),这些权衡考量都具有借鉴意义。
在未看到图片的情况下证明字符串错误
替代文本的存在是一个客观事实:属性存在或不存在。但质量判断往往需要主观评估。机器无法通过标记代码证明某句话是否在上下文中充分描述了图片内容。
不过,并非所有质量判断都具有主观性。仅通过替代文本本身就能执行以下检查,无需参考图片内容:
- 属性缺失(非空字符串)或仅包含空白字符
- 替代文本是文件名,如
hero.png、IMG_2847.jpg - 替代文本是占位符,如
TODO、tbd - 替代文本使用通用词汇描述媒介而非内容,如
image、logo、chart - 相邻图片重复使用相同的替代文本
这些都属于对字符串的判断,这成为我们的分界线。默认运行的5条确定性规则无需调用AI模型或网络接口。一条可选规则会调用模型,结合图片内容和上下文进行判断,这是单靠替代文本字符串无法支持的。
首先,我们必须确定在扫描的网页上对哪些图片进行判断。我们使用 Playwright 的基于角色的定位器,而不是 querySelectorAll('img'),因此任何未包含在浏览器 无障碍树 中的内容都会被排除,包括带有 alt="" 的内容。最后这个排除项尤为重要。空的 alt 是作者明确表示图片具有装饰性,而标记它会惩罚你希望鼓励的行为。
那么,严格程度应该如何把握?质量检查器的成败取决于误报,因此我们选择使用封闭集合而非巧妙的启发式方法。vague-alt 规则会先对字符串进行标准化,然后与精心挑选的、本身不携带信息的词汇列表进行匹配。它仅在完全匹配时触发:
alt="image"会被标记。alt="image of the login screen with the SSO button highlighted"不会。
这种字面规则会遗漏许多糟糕的 alt 文本。我们选择接受遗漏而非误报,因为开发者启用的可靠检查器胜过被关闭的检查器。
重复是布局问题,而非 DOM 问题
重复的 alt 文本带来了有趣的挑战。设想一行五个星形图标,每个都标注着 "3/5 stars"。屏幕阅读器用户会听到五次相同的内容,而其中四次并未提供新信息。
我们最初版本的实现是按文档顺序遍历图片,并标记任何具有相同标准化 alt 的连续序列。但它误判了一些情况。例如,页脚的“GitHub”标志和页眉的“GitHub”标志可能在提取的列表中相邻,但在屏幕上却相距甚远,因此没有人会将它们视为一组。
真正重要的是图片在屏幕上的位置,而非其在标记中的位置。因此,规则现在会检查页面布局,仅在两个边界框之间的间隙相对于框本身较小时才延长连续序列:
const gap = Math.max(horizontalGap, verticalGap)
const largerDim = Math.max(a.boundingBox.width, a.boundingBox.height,
b.boundingBox.width, b.boundingBox.height)
return gap > GAP_MULTIPLIER * largerDim两个值得注意的细节:
- 乘数是一个判断值,而非我们从任何数据中推导出的数字。这种值需要通过实际页面进行调整,而非依赖规范。
- 当任一图片没有可测量的边界框时,检查会失败并继续运行。缺失的发现是隐形的;错误的发现则会暴露出来。
让模型像审稿人而非批评者一样工作
确定性规则只需 alt 字符串即可。任何更智能的规则都需要了解页面内容,而这些信息并未被图片元素记录。alt="a smiling person" 是否合适,完全取决于其上下文:在一张通用的情绪照片中,它可能有效。但如果在标题中提到了特定人物,它就缺乏足够的细节。
在我们可选的 alt-text-quality 检查中,我们会为每张图片提取页面上下文:最近的标题、页面标题、任何 <figcaption>、图片是否位于链接或按钮内,以及附近最多 600 字符的文本。
链接信号最为关键,因为当图片是链接的唯一内容时,其 alt 文本会成为链接的可访问名称。此时正确的 alt 应该命名目标,而非描述图片。
一个注意事项: 该插件仅记录图像位于链接内部的事实。我们不会检查该图像是否是链接的唯一内容,而唯一内容才是将替代文本转换为链接名称的关键部分。因此目前这两种情况在模型看来是完全相同的。
该上下文、替代文本和图像会通过 GitHub Models 发送给视觉模型。我们的失败模式很少是模型误读图片,而是模型产生了主观意见。即使有完美的替代文本,我们最初版本的检查器仍会建议不同的替代文本,因为“这能改进吗?”这个问题语言模型总是会回答“是的”。每个图像都会变成一个发现项,导致信号完全消失。
以下三个改进解决了这个问题:
- 采用决策流程而非指令。 提示信息会依次执行四个步骤,遇到第一个匹配的步骤即停止,并输出该步骤的结论:装饰性、与标题重复、功能性或信息性。
- 明确的反挑剔规则。 信任作者的表述框架。将冗余前缀(“图片的…”)与语义性前缀(“照片的…”)区分开。当周围文字已对图像进行分析时,简短的替代文本应被视为_正确_。
- 结构化输出并强制字段顺序, 使
reasoning字段必须在verdict字段之前生成,模型必须构建论证后才能选择标签。
这些改进并不能让模型变得绝对正确,但能让其达到足够一致性以支持迭代。该仓库包含一个由公开教学材料构建的离线评分框架:WebAIM、W3C 图像教程 和 POET。规则和评分框架共享同一个提示,因此你在离线时调整的内容也会在 CI 中运行。不过该评分框架仅测试模型的判断,不测试整个流程。某个案例可能在此获得满分却从未在真实扫描中被模型处理。
向模型发送图像是一项隐私和成本决策
当检查器调用外部模型处理网页数据时,它就不再只是一个代码规范规则,而需要谨慎设计数据流。由此带来以下影响:
- 该规则默认关闭。 除非你主动在插件配置中启用,否则不会运行,且需要拥有访问 GitHub Models 的令牌。
- URL 会被脱敏。 图像 URL 和链接
href通常包含签名的 CDN 令牌或会话标识,因此任何进入模型上下文或规则错误日志的内容都会被剥离查询参数和片段。出于相同原因,我们发送给模型的标记中src和srcset会被替换为(omitted)。 - 该上下文窗口中的所有内容都视为不可信输入。 标题、标题和正文都来自被扫描的页面,而页面可能包含旨在引导模型的文本。结构化输出限制了响应的格式,但不会限制背后的推理过程。
一个注意事项,因为这份列表容易被过度解读: 检查结果仍会将真实的页面 URL 和原始 HTML 通过扫描器的常规报告流程传递。这是有意为之,因为你无法修复无法定位的图像。脱敏仅限制了到达模型和日志的内容,而不是到达你自身问题跟踪系统的内容。如果你设置了 Azure AI Vision 凭据,可选的 OCR 预处理步骤会将图像字节发送到第二个位置。虽然 Azure 并非强制要求,但数据流审查必须覆盖这两条路径。
成本遵循相同的模式。在常见情况下,这是每个图像每次扫描一次模型调用,对于以图片为主的网站来说,这会主导整个运行的总成本。这已经足够说明为什么应该将其安排在计划中,而不是每次提交都执行。
仍无法实现的功能
- 确定性规则是字面意义上的。 它们能检测到明显未编写的替代文本,但无法识别流畅但错误的替代文本。它们还会读取
alt属性,而不是计算出的可访问名称,因此即使aria-label修复了问题,也不会阻止该发现。 - 基于模型的规则会产生误报。 每个发现都应作为需要人工关注的提示,而不是最终结论。
- 静默不等于覆盖范围。 该规则会在浏览器会话之外重新获取图像,因此任何需要身份验证的内容可能无法加载。获取和模型错误会被记录并跳过,这意味着页面可能返回干净的结果,因为没有任何内容被检查。
- 建议的替代文本是草案。 仅看到图像和附近几个词的模型无法考虑您的受众、您的公司风格或图像在整个页面中的作用。
- 某些发现与扫描器内置检查重复。 因为我们的
missing-alt规则覆盖了相同的内容。 - 我们只检查 HTML
<img>标签。 SVG、role="img"容器、CSS 背景和画布尚未被覆盖。 - 这是新代码,缺乏实际反馈。 这类规则在接触真实网站上各种标记和内容后会得到改进。该插件尚未经历这一过程,因此请相应对待早期发现。
- 通过检查不等于符合规范。 自动检查是最低标准。使用辅助技术的人进行测试才是目标。
如果你在构建类似工具,我们想告诉你的事
将你能证明的内容与你只能怀疑的内容区分开,并为它们设置不同的默认值。能够证明某事的检查应廉价、可预测且默认启用。只能怀疑某事的检查应为可选,应表达为建议而非最终结论。然后,询问用户的实际体验,而不是 DOM 的说法。这个插件中所有仍存在的缺口都遵循这种模式。我们记录图像位于链接内部,而不是它就是链接。我们读取属性,而不是计算出的名称。
这种距离才是真正的边界,更好的模型也无法消除它。判断图像对无法查看它的用户的功能仍需要人工判断。自动化能为你带来的好处是确保人工检查者对正确的图像进行二次审查。
[在你的无障碍扫描工作流程中尝试替代文本插件。](https://github.com/github/accessibility-scanner-alt-text-plugin) 如果它告诉了你错误的信息,请报告。在 问题跟踪器 中提交报告,附上发现内容,如果页面是公开的,请附上链接。
作者
Taarik Ashenafi 曾是 GitHub 障碍团队的软件工程实习生。
Keenan Zhou 曾是 GitHub 障碍团队的软件工程实习生。
了解更多 GitHub 内容
文档
在 GitHub 官方文档中,您能找到所有需要掌握 GitHub 的内容。
GitHub
在 GitHub 上构建未来,这里是任何人都能从任何地方构建任何事物的地方。
客户案例
了解使用 GitHub 进行构建的公司和工程团队。
GitHub Universe 2026
10月28-29日,加入我们在旧金山或在线参加 GitHub Universe——我们的旗舰开发者大会,汇聚全球开发者、代理和代码。