首页
/ Front-End-Checklist 的 alt-text 技能:面向人类与 AI Agent 的图片替代文本审查与修复实战指南

Front-End-Checklist 的 alt-text 技能:面向人类与 AI Agent 的图片替代文本审查与修复实战指南

2026-09-04 17:19:35作者:温玫谨Lighthearted

本篇技术指南以 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.mdxcheck/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 给出了四条核心判据,可作为代码评审时的速查卡:

  1. 每个 <img> 都必须有 alt 属性——完全省略它本身就违反 WCAG 2.1 SC 1.1.1;
  2. 装饰性图片使用 alt="",让屏幕阅读器跳过它们;
  3. alt 文本应描述图片的"用途/传达的信息",而不是它的外观
  4. 作为链接的图片:alt 描述的是链接目标,而不是图片本身的样子

一个常见误区值得在评审时特别强调:"烂 alt 文本(如 alt="image")和没有 alt 文本一样糟"。而装饰性图片必须显式使用 alt="",因为省略 alt 会导致某些屏幕阅读器朗读出文件名。

三、Check 检查流程:如何系统性地扫描代码库

SKILL.md 的 Check 章节定义了一套五步扫描流程,要求遍历代码库中所有 <img> 元素并逐一核验:

  1. 每个 <img> 都有 alt 属性(缺失 alt 即为错误);
  2. 装饰性图片使用 alt=""
  3. 有信息量的图片具有描述性文本,传达图片的含义,而不仅仅是文件名;
  4. 作为链接的图片描述的是跳转目标
  5. 图片中的文字在 alt 中原样复现

同时需要重点标记三类典型反模式:

  • <img> 完全没有 alt
  • alt 值就是文件名(例如 alt="photo1.jpg");
  • alt 值是泛化占位词(例如 alt="image"alt="photo")。

这套检查逻辑在仓库的 MCP 检测器中有直接的机器化实现。packages/mcp/src/tools/check-rule.ts 中针对 alt 类规则(slug 包含 altalternative)的启发式检测如下:

// 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 DevToolsWAVE——两者都会标记缺失的、或非装饰性图片上的空 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-imagestext-in-images 等相邻规则),供 Agent 在检索规则时沿图展开。

八、小结:把一条检查清单规则做成可执行工程

围绕 skills/alt-text/SKILL.md,本仓库展示的是一套完整的"规则工程化"范式:

  1. 对人类:Quick Reference 四条判据 + 五类图片的 Fix 写法 + 自动化/手动双重验证,15 分钟即可完成一轮修复;
  2. 对 AI Agent:Check/Fix/Explain/Code Review 四段结构化 prompt 让 Agent 能直接执行扫描、修复、解释与评审动作;
  3. 对工程基建check-rule.tsreview-code.ts 中的启发式与 DOM 级检测,把"缺失 alt 是错误、空 alt 是装饰图的正确写法、<picture> 回退图豁免"这些语义精确落地为可运行、可测试的代码。

掌握这套流程后,你既可以把它当作图片无障碍的人工评审清单,也可以直接交给 Agent 对任意代码库执行同标准的自动化审查。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384