关于 progressive-enhancement
面向 Web 功能开发与架构评审的无障碍技能,指导先确保语义 HTML 可用,再逐层增强 CSS、JavaScript 和离线能力。也涵盖渐进增强与可持续性的联系。
主要功能
- 01以语义 HTML 支撑核心内容和任务
- 02逐层增强样式与交互
- 03尊重 CSS 用户偏好
- 04为脚本失败和动态内容提供回退
- 05使用特性检测和服务工作者离线模式
适用场景
- 01检查页面在禁用 JavaScript 时的可用性
- 02设计无需 JavaScript 提交的表单和导航
- 03为前端框架规划服务端渲染或静态生成
- 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 标准。请勿在审计或合规声明中引用该标准。
参考资料
- 完整的最佳实践指南
- SUSTAINABILITY.md — PE 可减少页面体积和能源消耗;参见 WSG 对齐情况
- Web 可持续性指南(WSG)1.0
- MDN:Service Worker API
- MDN:离线和后台运行
标准展望: WCAG 3.0 正在制定中。预计渐进增强原则不会发生破坏性变更。 请关注:https://www.w3.org/TR/wcag-3.0/