Front-End-Checklist 的 alt-text 技能:面向人类与 AI Agent 的图片替代文本审查与修复实战指南
本篇技术指南以 skills/alt-text/SKILL.md 为核心,完整拆解 Front-End-Checklist 仓库中"为图片提供有意义的 alt 文本"这一条 critical 级规则:包括它的检查清单(Check)、修复方案(Fix)、标准解释(Explain)与代码审查要求(Code Review),并结合仓库中 MCP 工具包 的实际检测源码,说明这套规则是如何被 AI Agent 机器化执行的。读完后,你将掌握一套可直接落地的图片无障碍审查流程,并理解"缺失 alt 是错误、空 alt 是装饰性图片的正确写法"这一关键区分在自动化检测中的实现方式。
一、规则定位:一条 Skill、一份参考文档、一份规则内容源
在 Front-End-Checklist 中,"alt text"并不是零散的一篇文章,而是一套为 AI Agent 设计的结构化技能(Skill)文档体系。理解这三个文件的关系,是后续所有实操的基础:
| 文件 | 作用 |
|---|---|
| skills/alt-text/SKILL.md | Agent 技能入口,包含 Quick Reference / Check / Fix / Explain / Code Review 五段核心指令 |
| skills/alt-text/references/rule.md | 技能的参考文档,包含完整的 HTML/React/Next.js 代码示例与验证方法 |
| packages/content/rules/en/images/alt-text.mdx | 站点规则页的内容源,携带完整 frontmatter 元数据(分类、优先级、关联规则、校验工具等) |
skills/alt-text/SKILL.md 的 frontmatter 明确声明了这条技能的关键属性:
name: alt-text
metadata:
category: images
priority: critical
difficulty: beginner
estimatedTime: "15"
source: frontendchecklist.io
category: images:归属于图片类规则;priority: critical:在整份前端检查清单中属于最高优先级,因为它违反的是 WCAG 2.1 的 Level A(最低门槛)要求;difficulty: beginner+estimatedTime: 15:面向初学者,预计 15 分钟即可完成一次完整修复;source: frontendchecklist.io:规则上游来源,说明该技能是从站点规则内容派生而来——这与 packages/content/rules/en/images/alt-text.mdx 中check/fix/explain三段 prompt 逐字对应的事实相互印证,两者是同一规则在"Agent 技能"与"人类阅读"两种形态下的表达。
规则的官方摘要(来自 rule.md 开头)是:
Every informative image has a descriptive alt attribute; decorative images use
alt=""to be ignored by screen readers.
即:每张有信息量的图片都必须有描述性的 alt 属性;装饰性图片使用 alt="" 以被屏幕阅读器忽略。
二、为什么重要:无障碍、合规与搜索引擎三重收益
SKILL.md 开篇给出了这条规则为什么被定为 critical 的事实依据:
- 全球约有 22 亿人存在视力障碍,屏幕阅读器会朗读
alt属性——缺少有意义的 alt 文本,视障用户将获得图片内容的零信息; - 缺失 alt 文本会不通过 WCAG 2.1 Success Criterion 1.1.1(非文本内容),这是 Level A(最低级别)的强制要求;
- 搜索引擎同样依赖 alt 文本索引图片内容,因此这条规则同时兼顾 SEO。
SKILL.md 的 Quick Reference 给出了四条核心判据,可作为代码评审时的速查卡:
- 每个
<img>都必须有alt属性——完全省略它本身就违反 WCAG 2.1 SC 1.1.1; - 装饰性图片使用
alt="",让屏幕阅读器跳过它们; - alt 文本应描述图片的"用途/传达的信息",而不是它的外观;
- 作为链接的图片:alt 描述的是链接目标,而不是图片本身的样子。
一个常见误区值得在评审时特别强调:"烂 alt 文本(如 alt="image")和没有 alt 文本一样糟"。而装饰性图片必须显式使用 alt="",因为省略 alt 会导致某些屏幕阅读器朗读出文件名。
三、Check 检查流程:如何系统性地扫描代码库
SKILL.md 的 Check 章节定义了一套五步扫描流程,要求遍历代码库中所有 <img> 元素并逐一核验:
- 每个
<img>都有alt属性(缺失 alt 即为错误); - 装饰性图片使用
alt=""; - 有信息量的图片具有描述性文本,传达图片的含义,而不仅仅是文件名;
- 作为链接的图片描述的是跳转目标;
- 图片中的文字在 alt 中原样复现。
同时需要重点标记三类典型反模式:
<img>完全没有alt;- alt 值就是文件名(例如
alt="photo1.jpg"); - alt 值是泛化占位词(例如
alt="image"、alt="photo")。
这套检查逻辑在仓库的 MCP 检测器中有直接的机器化实现。packages/mcp/src/tools/check-rule.ts 中针对 alt 类规则(slug 包含 alt 或 alternative)的启发式检测如下:
// Alt text check
if (slug.includes('alt') || slug.includes('alternative')) {
const imgMatches = code.match(/<img[^>]*>/gi) || []
for (const img of imgMatches) {
if (!img.includes('alt=') && !img.includes('alt =')) {
checks.push({
condition: true,
issue: 'Found <img> element without alt attribute'
})
} else if (img.match(/alt\s*=\s*["']\s*["']/)) {
// Empty alt is sometimes intentional for decorative images
// Only flag if not explicitly decorative
if (!img.includes('role="presentation"') && !img.includes('aria-hidden')) {
checks.push({
condition: true,
issue: 'Found <img> with empty alt attribute (may be intentional for decorative images)'
})
}
}
}
}
这段源码恰好把 SKILL.md 中的两条关键语义落成了可执行逻辑:缺失 alt 直接报错误,而空 alt 只在图片没有 role="presentation" 或 aria-hidden 等装饰性标记时才提示(因为空 alt 对装饰图是正确写法)。这提示开发者:当你为装饰图保留 alt="" 时,配合显式的 role="presentation" / aria-hidden="true" 可以让自动化工具不误报。
packages/mcp/src/tools/review-code.ts 中的 checkRule 函数则给出了简化版——同样基于 <img 标签正则匹配,凡 slug 命中 alt 相关规则且发现无 alt= 的标签,立即返回 Found <img> element without alt attribute。
更精细的检测位于 packages/mcp/src/tools/review-code.ts:这里改用真实 DOM 解析来区分"缺失 alt"与"空 alt"两种不同语义,并额外豁免了 <picture> 内部的回退 <img>:
// ── alt distinction: images with explicitly empty alt="" vs missing alt (different semantics)
// Missing alt is a real issue; empty alt is correct for decorative images
const imgsWithoutAlt = root.querySelectorAll('img:not([alt])').filter(img => {
// Exclude images inside <picture> that are purely fallback
const parent = img.parentNode
return parent?.rawTagName?.toLowerCase() !== 'picture'
})
if (imgsWithoutAlt.length > 0) {
const srcs = imgsWithoutAlt
.slice(0, 3)
.map(img => img.getAttribute('src') ?? '(no src)')
.join(', ')
issues.set(
'alt-tags',
`${imgsWithoutAlt.length} <img> element(s) missing alt attribute: ${srcs}`
)
issues.set('alt-text', issues.get('alt-tags')!)
}
从源码结构看,这里有两点值得注意:其一,检测只匹配 img:not([alt]),即只把"属性缺失"算作问题,alt="" 不在此列,与规则的"空 alt 对装饰图正确"的语义严格一致;其二,报告最多列出前 3 个问题图片的 src,方便 Agent 定位到具体资源。相关测试用例 packages/mcp/tests/unit/review-code-detection.test.ts 中也以 alt-text 规则为核心场景做了检测断言,可以推断这套行为是被测试持续守护的。
四、Fix 修复方案:五类图片的 alt 写法
SKILL.md 的 Fix 章节针对"缺失或质量差的 alt 文本"给出了五类场景的标准修复方式,下面结合 rule.md 中的完整代码示例逐一展开。
4.1 有信息量的图片:描述"它传达什么",而不是"它长什么样"
例如不要写 alt="chart",而要写 alt="Bar chart showing 40% increase in sales Q3 2024"。rule.md 给出了对照示例:
<!-- ❌ Bad: Missing alt -->
<img src="revenue-chart.png">
<!-- ❌ Bad: Filename as alt -->
<img src="revenue-chart.png" alt="revenue-chart.png">
<!-- ❌ Bad: Generic alt -->
<img src="revenue-chart.png" alt="chart">
<!-- ✅ Good: Describes what the image conveys -->
<img
src="revenue-chart.png"
alt="Bar chart showing Q3 2024 revenue increased 40% year-over-year, reaching $2.4M"
>
4.2 装饰性图片:用 alt="" 或改用 CSS 背景图
纯视觉装饰的图片不承载信息,应将其从辅助技术中隐藏:
<!-- ❌ Bad: No alt attribute—screen reader may announce the filename -->
<img src="decorative-swirl.png">
<!-- ✅ Good: Empty alt hides image from screen readers -->
<img src="decorative-swirl.png" alt="">
<!-- ✅ Good: Or use CSS background images for decoration -->
<div class="decorative-swirl" aria-hidden="true"></div>
注意第三种写法:把装饰完全改为 CSS 背景 + aria-hidden="true" 的纯样式元素,从源头上避免 <img> 语义带来的朗读风险。
4.3 作为链接使用的图片:alt 描述链接目标
当 <img> 位于 <a> 内部时,alt 必须描述跳转目的地而非外观:
<!-- ❌ Bad: Describes appearance, not destination -->
<a href="https://twitter.com/example">
<img src="twitter-logo.svg" alt="Blue bird logo">
</a>
<!-- ✅ Good: Describes the link destination -->
<a href="https://twitter.com/example">
<img src="twitter-logo.svg" alt="Follow us on Twitter">
</a>
4.4 文字图片:把图中的文字原样复现到 alt
图片包含文字(如 logo、横幅、截图)时,将文字逐字复制到 alt:
<!-- ✅ Good: Alt reproduces the text shown in the image -->
<img src="sale-banner.png" alt="Summer Sale — 50% off all items">
<!-- ✅ Good: Logo with company name -->
<img src="logo.svg" alt="Acme Corp">
4.5 复杂图片(图表、信息图):短 alt + 长描述
对图表、组织架构图等复杂视觉,采用"简短 alt + 通过 aria-describedby 或可见标题(caption)提供长描述"的组合:
<!-- Using aria-describedby to link to a visible description -->
<figure>
<img
src="org-chart.png"
alt="Company organisational chart"
aria-describedby="org-chart-desc"
>
<figcaption id="org-chart-desc">
The chart shows three departments reporting to the CEO: Engineering (12 staff),
Marketing (8 staff), and Operations (5 staff).
</figcaption>
</figure>
这里 alt 只承担一句话的概括,figcaption 承载细节,且该描述对所有用户可见(不只是为了无障碍)——这一点与 mdx 中声明的关联规则 figure-figcaption("标题为复杂图片补充 alt 的可见描述")形成呼应。
五、框架层实践:React 组件化与 Next.js Image
rule.md 的 Framework Examples 章节给出了把 alt 规则固化为组件约束的两种常见做法(完整代码见 packages/content/rules/en/images/alt-text.mdx 的 Framework Examples 一节)。
React:封装 AccessibleImage 组件,把"装饰性 = 空字符串"的决策收敛到一处。
interface ImageProps {
src: string
alt: string
decorative?: boolean
}
function AccessibleImage({ src, alt, decorative = false }: ImageProps) {
return (
<img
src={src}
// Decorative images use empty string; informative images use descriptive text
alt={decorative ? '' : alt}
/>
)
}
// Usage
<AccessibleImage src="hero.jpg" alt="Team members collaborating in a modern office" />
<AccessibleImage src="divider.png" decorative />
这种写法的好处是:装饰图的"空 alt"不再依赖每个调用点的人为自觉,而是由 decorative 布尔属性强制表达意图,评审时只需检查 decorative 使用是否正确。
Next.js:next/image 本身就要求 alt,装饰图传 ""。
import Image from 'next/image'
// Next.js Image requires alt; use "" for decorative
function HeroBanner() {
return (
<>
{/* Informative */}
<Image
src="/hero.jpg"
alt="Product team celebrating a successful launch"
width={1200}
height={600}
priority
/>
{/* Decorative */}
<Image
src="/wave-divider.svg"
alt=""
width={1200}
height={60}
aria-hidden="true"
/>
</>
)
}
这里同时体现了 SKILL.md Code Review 章节的要求:评审时不仅要查标记(markup),还要结合"资源、标记与交付配置"一起看——装饰图在空 alt 之外又叠加 aria-hidden="true",是双重保险的典型写法,也正好能绕过上文 MCP 检测器对"裸空 alt"的提示。
六、Verification:自动化工具 + 手动核验
rule.md 的 Verification 章节给出了两级验证手段,这也是 SKILL.md 中 codeReview prompt 要求"描述如何在 DevTools 中确认修复"的具体落点。
6.1 自动化检查
- 在页面上运行 axe DevTools 或 WAVE——两者都会标记缺失的、或非装饰性图片上的空 alt;
- 使用 Lighthouse 无障碍审计——"Images do not have alternate text" 是计入评分的正式条目。
mdx 的 frontmatter 中也把这三者登记为该规则的标准工具(tools 字段):axe DevTools、WAVE Web Accessibility Evaluator、Lighthouse Accessibility Audit。
6.2 手动检查
- 启用屏幕阅读器(VoiceOver、NVDA 或 JAWS),用
G键在图片间跳转,逐个听朗读结果是否符合预期; - 检查 DevTools 的 Network 面板:对任意图片 URL,确认对应的
<img>拥有有意义的alt。
6.3 两个特殊场景
- CAPTCHA 图片:alt 应描述用途而不是字符本身(例如
alt="CAPTCHA: type the characters shown"),并按 WCAG 1.1.1 提供语音替代方案; - 带相邻文字标签的 SVG 图标:如果图标含义已被可见文字表达,应在 SVG 上使用
aria-hidden="true",而不是给 alt 重复语义。
七、规则元数据与关联规则:从单点修复到成体系治理
从 packages/content/rules/en/images/alt-text.mdx 的 frontmatter 可以看到,这条规则还声明了三条关联规则(relatedRules),构成图片无障碍的治理网络:
figure-figcaption:标题(caption)为复杂图片补充 alt 之外的可见描述;error-images:回退图片同样需要 alt 文本,保证主图加载失败时页面依然可访问;dimensions:两条规则都影响图片质量,通常一起评审。
同时,mdx 的 sources 字段把权威依据登记为两类:MDN 的 Responsive images(作为参考标准)与 web.dev 的 Image performance(作为实现指导),并在正文的 Standards 一节要求"在判定规则满足之前,先对照这两份标准检查实现"。这提示读者:alt 文本并非孤立属性,它和 srcset、<picture>、响应式尺寸等机制共同决定图片的最终可访问性与性能表现——这也解释了 MCP 检测器为何专门豁免 <picture> 内的回退 <img>。
对于 AI Agent 而言,mdx 中的 check/fix/explain/codeReview 四个 prompt 字段就是 SKILL.md 中四个章节的"数据源版本",而 packages/mcp/src/tools/get-rule.ts 中还为 alt-text 维护了知识图谱式的关联关系(如 responsive-images、text-in-images 等相邻规则),供 Agent 在检索规则时沿图展开。
八、小结:把一条检查清单规则做成可执行工程
围绕 skills/alt-text/SKILL.md,本仓库展示的是一套完整的"规则工程化"范式:
- 对人类:Quick Reference 四条判据 + 五类图片的 Fix 写法 + 自动化/手动双重验证,15 分钟即可完成一轮修复;
- 对 AI Agent:Check/Fix/Explain/Code Review 四段结构化 prompt 让 Agent 能直接执行扫描、修复、解释与评审动作;
- 对工程基建:check-rule.ts 与 review-code.ts 中的启发式与 DOM 级检测,把"缺失 alt 是错误、空 alt 是装饰图的正确写法、
<picture>回退图豁免"这些语义精确落地为可运行、可测试的代码。
掌握这套流程后,你既可以把它当作图片无障碍的人工评审清单,也可以直接交给 Agent 对任意代码库执行同标准的自动化审查。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00