mcpField
P
progressive-enhancement

progressive-enhancement

github.com/mgifford开发57136 次安装6 周前更新
代码仓库

关于 progressive-enhancement

面向 Web 功能开发与架构评审的无障碍技能,指导先确保语义 HTML 可用,再逐层增强 CSS、JavaScript 和离线能力。也涵盖渐进增强与可持续性的联系。

主要功能

  1. 01以语义 HTML 支撑核心内容和任务
  2. 02逐层增强样式与交互
  3. 03尊重 CSS 用户偏好
  4. 04为脚本失败和动态内容提供回退
  5. 05使用特性检测和服务工作者离线模式

适用场景

  1. 01检查页面在禁用 JavaScript 时的可用性
  2. 02设计无需 JavaScript 提交的表单和导航
  3. 03为前端框架规划服务端渲染或静态生成
  4. 04制定服务工作者缓存及离线回退方案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mgifford/accessibility-skills --skill progressive-enhancement

安装后在 Claude Code 中输入/progressive-enhancement确认已加载。

附带文件SYNC.md

详细介绍

渐进增强无障碍技能

规范来源:mgifford/ACCESSIBILITY.md 中的 examples/PROGRESSIVE_ENHANCEMENT_BEST_PRACTICES.md 此技能源自该文件。如有疑问,请以示例为准。

构建任何 Web 功能或审查架构决策时,请遵循以下规则。


核心要求

从稳固的基础开始,确保所有用户都能使用,然后再逐层添加增强功能。 每位用户——无论浏览器功能、网络速度、辅助技术或 JavaScript 是否可用——都必须能够访问核心内容并完成核心任务。

渐进增强也是一种可持续实践。无需 JavaScript 即可正常运行的页面会轻得多:传输的字节更少,解析和执行脚本所需的 CPU 更少,每次页面浏览消耗的能源也更少。请参阅 SUSTAINABILITY.md 和 Web Sustainability Guidelines。


严重程度等级(本技能)

等级含义
严重没有 JS/CSS 时无法访问核心内容或完成核心任务
高可以访问核心内容,但没有 JS/CSS 时体验会显著下降
中等增强功能可以平稳降级,但会带来不便
轻微未达到最佳实践;影响很小

三个层级

层级 1 — 语义化 HTML(始终必需)

此处出现问题属于严重问题。

  • 所有核心内容都能通过纯 HTML 阅读——无需 CSS 或 JS
  • 表单可使用浏览器原生行为提交
  • 导航可作为标准链接正常运行
  • 标题、列表、表格和地标准确反映文档结构
层级 2 — CSS(增强呈现效果)

此处出现问题属于中等到高严重程度。

  • 使用外部样式表;禁用样式表后不会丢失内容
  • 遵循用户偏好:prefers-reduced-motion、prefers-color-scheme、 prefers-contrast、forced-colors
  • 即使样式表加载失败,页面仍可使用
层级 3 — JavaScript(增强交互性)

依赖 JS 才能访问核心内容或完成核心任务,属于严重问题。

  • JS 用于增强,而非限制对核心内容或任务的访问
  • 通过脚本应用依赖 JS 的类或行为,而非写入静态标记
  • 妥善处理脚本故障——HTML 层仍必须可用
  • 使用功能检测,而非浏览器检测:
if ('fetch' in window && 'querySelector' in document) {
  // apply enhanced experience
}
层级 3 扩展 — Service Worker(离线能力)

Service Worker 属于层级 3 增强功能:它需要 JavaScript,由脚本注册;在不可用时(例如隐私浏览、不受支持的浏览器或无法使用 HTTPS)必须平稳降级。

正确实现后,它既能增强无障碍体验,也能提升可持续性:

  • 无障碍:网络连接不稳定的用户(农村地区、低收入家庭和发展中地区较为常见)可在离线时继续访问之前加载的内容
  • 可持续性:缓存响应可避免重复网络请求,减少数据传输量和每次页面浏览所需的服务器能耗
// Register Service Worker only if supported — classic PE feature detection
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').catch((err) => {
    // Registration failure: page continues to work normally without it
    console.warn('Service Worker registration failed:', err);
  });
}

离线回退模式:

// sw.js — cache-first with network fallback
const CACHE_NAME = 'v1';
const OFFLINE_URL = '/offline.html';

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) =>
      cache.addAll([OFFLINE_URL, '/', '/styles.css'])
    )
  );
});

self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith(
      fetch(event.request).catch(() => caches.match(OFFLINE_URL))
    );
  }
});

离线回退页面(/offline.html)本身必须是有效的层级 1 HTML 文档——具备语义结构,且无需 CSS 或 JS 即可阅读。

Service Worker 缓存策略(cache-first、network-first、stale-while-revalidate)应根据内容更新频率选择。对于频繁变化的内容,如果没有缓存失效方案,请避免采用会提供过期内容的缓存策略。


关键:核心内容不得依赖 JavaScript

仅通过 JavaScript 渲染页面内容属于关键问题——禁用 JS 的用户、遇到兼容性问题的 AT 用户,以及网络带宽较低的用户都会被完全排除在外。

  • 从服务器交付完整 HTML;在浏览器中增强交互
  • 核心内容必须包含在初始 HTML 响应中
  • 使用 React/Vue/Angular/Svelte 时:配置 SSR 或静态生成
  • 避免使用必须依赖 JS 才能渲染任何可见内容的 SPA 模式

每一字节无法用于访问核心内容的 JavaScript 都是多余的能源消耗。优先采用服务器端渲染——它只传输一次 HTML;而 JS 包传输的是代码,每次访问后都必须解析、编译并执行。


关键:表单必须在没有 JavaScript 的情况下也能使用


<form action="/search" method="get">
  <label for="query">Search</label>
  <input id="query" name="q" type="search">
  <button type="submit">Search</button>
</form>

可使用 JS 增强即时结果、自动补全或内联验证,同时保留由服务器处理的表单作为备用方案。

无法在没有 JS 的情况下提交的表单属于关键问题。


关键:导航必须在没有 JavaScript 的情况下也能使用


<nav aria-label="Main">
  <ul>
    <li><a href="/about">About</a></li>
    <li><a href="/contact">Contact</a></li>
  </ul>
</nav>

可使用 JS 增强下拉菜单或动画过渡效果。


严重:动态内容必须提供备用路径

if ('fetch' in window) {
  loadContentAsync(url);
} else {
  // Standard link navigation works automatically
}

只有确认基础内容在没有 aria-live 区域的情况下也能正常访问后,才使用这些区域。


中等:必须尊重 CSS 用户偏好

prefers-reduced-motion、prefers-color-scheme、prefers-contrast 和 forced-colors 属于第 2 层的职责。忽略这些偏好至少属于中等问题;若忽略 prefers-reduced-motion,导致快速或闪烁的动画,则可能达到严重级别。


应避免的做法

  • 仅通过 JavaScript 渲染页面内容——关键
  • 对 HTML 层所需内容使用 display:none / visibility:hidden——关键
  • 要求通过 JS 在页面之间导航,且没有服务器渲染的备用方案——关键
  • 使用 user-scalable=no——严重(会阻止弱视用户缩放)
  • 假设脚本一定会执行——始终处理失败状态
  • 将 Polyfill 用作渐进增强的替代方案(Polyfill 会修补功能;渐进增强则是在功能缺失时依然可用)
  • 为本可在服务器端渲染的功能交付大型 JS 包——这既会带来无障碍风险,也会增加可持续性成本

完成标准检查清单

  • 禁用 JavaScript 后仍可阅读核心内容
  • 禁用 JavaScript 后仍可完成核心任务
  • 表单通过浏览器原生行为提交
  • 导航通过标准 HTML 链接正常工作
  • CSS 尊重 prefers-reduced-motion、prefers-color-scheme、prefers-contrast
  • 妥善处理脚本执行失败
  • 使用功能检测(而非浏览器检测)
  • 为 JS 框架配置 SSR 或静态生成
  • 注册 Service Worker 时进行功能检测,并在失败时静默处理
  • 离线备用页面是有效的第 1 层 HTML
  • 记录缓存策略,并使其与内容更新频率相匹配
  • 已测试:禁用 JS → 验证核心内容;禁用 CSS → 验证逻辑阅读顺序

关键 WCAG 标准

  • 2.1.1 键盘(A)——原生元素内置键盘支持
  • 4.1.2 名称、角色、值(A)

**注意:**WCAG 4.1.1 解析已于 WCAG 2.2 中移除(2023 年 8 月)。 现代浏览器会以统一方式处理解析错误。有效的语义 HTML 仍然是渐进增强的重要基础,但它已不再是可测试的 WCAG 标准。请勿在审计或合规声明中引用该标准。

参考资料

标准展望: WCAG 3.0 正在制定中。预计渐进增强原则不会发生破坏性变更。 请关注:https://www.w3.org/TR/wcag-3.0/

评论

支持 Markdown