mcpField
F
framework-accessibility

framework-accessibility

github.com/community-access开发429250 次安装今天更新
代码仓库

关于 framework-accessibility

为 React、Next.js、Vue、Angular、Svelte 和 Tailwind CSS 提供无障碍模式参考的技能,适合前端开发者。内容按框架列出常见问题和修复示例,涵盖键盘操作、焦点管理、动态内容与对比度。

主要功能

  1. 01按框架整理常见无障碍问题
  2. 02提供代码修复模板
  3. 03涵盖键盘可访问性与焦点管理
  4. 04提供 Tailwind CSS 对比度组合

适用场景

  1. 01审查前端组件的无障碍实现
  2. 02修复框架特有的焦点问题
  3. 03为 Tailwind 界面检查颜色对比度

安装

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

$npx skills add https://github.com/community-access/accessibility-agents --skill framework-accessibility

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

详细介绍

特定框架的无障碍模式

React / Next.js

常见陷阱
模式问题修复方法
在 <div> 上使用 onClick无法通过键盘访问使用 <button>,或添加 role="button"、tabIndex={0}、onKeyDown
dangerouslySetInnerHTML可能注入无障碍性不足的内容审核注入的 HTML,检查 ARIA、标题和替代文本
将 React.Fragment 作为根节点可能破坏地标树确保片段不会打断地标嵌套
列表缺少 key重新渲染时可能导致焦点丢失对交互式列表使用稳定的键(不要使用数组索引)
Portal 未设置焦点陷阱焦点可能移至背景内容使用 FocusTrap 组件包裹 Portal 内容
使用 useEffect 管理焦点挂载时焦点可能不会触发使用 useRef + useEffect,并设置正确的依赖数组
修复模板
// Bad: div as button
<div onClick={handleClick}>Submit</div>

// Good: semantic button
<button onClick={handleClick}>Submit</button>

// Bad: image without alt in Next.js
<Image src="/hero.jpg" width={800} height={400} />

// Good: image with alt
<Image src="/hero.jpg" width={800} height={400} alt="Team collaborating in a modern office" />

// Bad: no focus management on route change
useEffect(() => {
  // nothing
}, [location]);

// Good: focus management on route change
useEffect(() => {
  const mainContent = document.getElementById('main-content');
  if (mainContent) {
    mainContent.focus();
    mainContent.scrollIntoView();
  }
}, [location]);

// Bad: link opening new tab
<a href={url} target="_blank">Resource</a>

// Good: link with new tab warning
<a href={url} target="_blank" rel="noopener noreferrer">
  Resource <span className="sr-only">(opens in new tab)</span>
</a>

Vue

常见陷阱
模式问题修复方法
对用户内容使用 v-html可能注入无障碍性不足的标记清理并审核注入的 HTML
对实时区域使用 v-if会从 DOM 中移除元素,导致播报失效对实时区域改用 v-show
<transition> 未管理焦点内容过渡时焦点丢失在 @after-enter 钩子中管理焦点
将 <teleport> 指向 body内容位于应用地标树之外为传送的内容添加地标角色
修复模板

<div v-if="message" aria-live="polite">{{ message }}</div>


<div v-show="message" aria-live="polite">{{ message }}</div>


<transition name="fade">
  <div v-if="showModal" class="modal">...</div>
</transition>


<transition name="fade" @after-enter="focusModal">
  <div v-if="showModal" ref="modal" class="modal" tabindex="-1">...</div>
</transition>

Angular

常见陷阱
模式问题修复方法
绑定 [aria-label]无效——ARIA 不是属性使用 [attr.aria-label]
*ngFor 未使用 trackBy列表重新渲染时焦点丢失添加 trackBy 函数
未使用 LiveAnnouncer路由更改不会播报注入 LiveAnnouncer 并播报导航信息
OnPush + 实时区域变更检测可能不会触发使用 ChangeDetectorRef.markForCheck()
修复模板
// Bad: ARIA binding
<button [aria-label]="label">X</button>

// Good: ARIA attribute binding
<button [attr.aria-label]="label">X</button>

// Bad: ngFor without trackBy
<li *ngFor="let item of items">{{ item.name }}</li>

// Good: ngFor with trackBy
<li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>

// Route change announcements
constructor(private liveAnnouncer: LiveAnnouncer, private router: Router) {
  this.router.events.pipe(
    filter(event => event instanceof NavigationEnd)
  ).subscribe((event: NavigationEnd) => {
    this.liveAnnouncer.announce(`Navigated to ${this.getPageTitle()}`);
  });
}

Svelte

常见陷阱
模式问题修复方法
{#if} 未管理焦点内容出现时焦点丢失使用 use:action 将焦点移至新内容
transition: 未检查动画偏好无论用户偏好如何,动画都会播放添加 prefers-reduced-motion 检查
在非交互元素上使用 on:click无法通过键盘访问使用 <button> 或添加键盘处理器
修复模板

<div on:click={toggle}>Toggle</div>


<button on:click={toggle}>Toggle</button>


<div transition:fly={{ y: 200 }}>Content</div>


<div transition:fly={{ y: reducedMotion ? 0 : 200, duration: reducedMotion ? 0 : 300 }}>Content</div>

<script>
  const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
</script>

Tailwind CSS

常见陷阱
模式问题修复方法
outline-none移除焦点指示器搭配使用 ring-2 ring-offset-2 focus-visible:ring-blue-500
在 bg-white 上使用 text-gray-400对比度未达到 4.5:1使用 text-gray-600 或更深的颜色
缺少 motion-reduce: 变体动画忽略用户偏好添加 motion-reduce:transition-none
缺少 focus: 样式没有可见的焦点指示器添加 focus:ring-2 focus:ring-blue-500
缺少 sr-only屏幕阅读器无法获取文本添加 <span class="sr-only">description</span>
确保对比度的 Tailwind 配对
背景最低文本颜色比率
bg-whitetext-gray-6004.55:1
bg-whitetext-gray-7006.62:1
bg-gray-50text-gray-7006.29:1
bg-gray-900text-gray-3005.92:1
bg-blue-600text-white5.23:1
bg-red-600text-white4.54:1
bg-green-700text-white4.58:1
修复模板

<button class="bg-blue-500 text-white px-4 py-2 rounded outline-none">
  Submit
</button>


<button class="bg-blue-500 text-white px-4 py-2 rounded focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">
  Submit
</button>


<p class="text-gray-400">Important information</p>


<p class="text-gray-700">Important information</p>


<div class="transition-transform duration-300 hover:scale-105">Card</div>


<div class="transition-transform duration-300 hover:scale-105 motion-reduce:transition-none motion-reduce:hover:scale-100">Card</div>

评论

支持 Markdown