accessibility-fundamentals
JSXでインタラクティブな要素やフォームなどをレビューする際に、WCAGに準拠したアクセシビリティとインクルーシブデザインを自動でチェックし、より多くの人が使いやすいWebサイトやアプリを作成するSkill。
📜 元の英語説明(参考)
Auto-invoke when reviewing JSX with interactive elements, forms, buttons, or navigation. Enforces WCAG compliance and inclusive design.
🇯🇵 日本人クリエイター向け解説
JSXでインタラクティブな要素やフォームなどをレビューする際に、WCAGに準拠したアクセシビリティとインクルーシブデザインを自動でチェックし、より多くの人が使いやすいWebサイトやアプリを作成するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o accessibility-fundamentals.zip https://jpskill.com/download/18276.zip && unzip -o accessibility-fundamentals.zip && rm accessibility-fundamentals.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/18276.zip -OutFile "$d\accessibility-fundamentals.zip"; Expand-Archive "$d\accessibility-fundamentals.zip" -DestinationPath $d -Force; ri "$d\accessibility-fundamentals.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
accessibility-fundamentals.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
accessibility-fundamentalsフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
アクセシビリティの基礎レビュー
「アクセシビリティは機能ではなく、要件です。ユーザーの15%があなたのアプリを使用できない場合、あなたは15%のユーザーを失敗させています。」
適用するタイミング
このスキルは、以下の場合に有効にします。
- ボタン、リンク、またはフォームを含む JSX をレビューするとき
- カスタムのインタラクティブなコンポーネントを見るとき
- 入力とラベルを持つフォーム
- ナビゲーションメニュー
- モーダルダイアログ
- ユーザーインタラクションコード全般
アクセシビリティチェックリスト
必須 (すべてのインタラクティブな要素)
- [ ] キーボード操作可能 — すべてのアクションが Tab + Enter/Space で動作する
- [ ] フォーカス表示 — フォーカスされた要素の明確な視覚的インジケーター
- [ ] セマンティック要素 —
<div onClick>ではなく<button> - [ ] フォームラベル — すべての入力に
<label>が関連付けられている - [ ] 代替テキスト — 画像に説明的な
alt属性がある - [ ] 十分なコントラスト — テキストが背景に対して読みやすい (4.5:1 の比率)
あると望ましい (複雑なインタラクション)
- [ ] ARIA ラベル — アイコンのみのボタンに
aria-labelがある - [ ] フォーカストラップ — モーダルが閉じられるまでフォーカスをトラップする
- [ ] スキップリンク — キーボードユーザー向けの「メインコンテンツにスキップ」
- [ ] ライブリージョン — 動的なコンテンツがスクリーンリーダーにアナウンスされる
- [ ] エラーメッセージ —
aria-describedbyで入力にリンクされている
絶対にしないこと
- [ ] 色だけに頼る — 色は唯一の指標であってはならない
- [ ] フォーカスのアウトラインを削除する — 代替手段なしに
outline: noneにしない - [ ] ボタンに div を使用する — セマンティックな
<button>または<a>を使用する - [ ] ユーザーを閉じ込める — モーダル/メニューからの脱出手段を常に提供する
よくある間違い (アンチパターン)
1. Div をボタンとして使用
// ❌ BAD: キーボード操作不可、セマンティクスなし
<div onClick={handleClick} className="button">
Click me
</div>
// ✅ GOOD: ネイティブのボタン要素
<button onClick={handleClick} className="button">
Click me
</button>
重要な理由: <div onClick> はキーボードフォーカスを受け取らず、Enter/Space に応答せず、スクリーンリーダーによってボタンとしてアナウンスされません。
2. フォームラベルの欠落
// ❌ BAD: 入力にラベルがない
<input type="email" placeholder="Email" />
// ✅ GOOD: ラベルが入力にリンクされている
<label htmlFor="email">Email</label>
<input id="email" type="email" placeholder="example@email.com" />
// ✅ ALSO GOOD: ラベルでラップする
<label>
Email
<input type="email" />
</label>
3. アイコンのみのボタン
// ❌ BAD: アクセシブルな名前がない
<button onClick={handleDelete}>
<TrashIcon />
</button>
// ✅ GOOD: スクリーンリーダー用の ARIA ラベル
<button onClick={handleDelete} aria-label="Delete item">
<TrashIcon aria-hidden="true" />
</button>
4. フォーカススタイルの削除
/* ❌ BAD: フォーカスが見えない */
button:focus {
outline: none;
}
/* ✅ GOOD: カスタムだが可視のフォーカス */
button:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.6);
}
/* ✅ BEST: focus-visible を使用する */
button:focus-visible {
outline: 2px solid #4299e1;
outline-offset: 2px;
}
5. 説明的でないリンクテキスト
// ❌ BAD: 「ここをクリック」はスクリーンリーダーに何も伝えない
<p>
To read our privacy policy, <a href="/privacy">click here</a>.
</p>
// ✅ GOOD: リンクテキストが宛先を説明する
<p>
Read our <a href="/privacy">privacy policy</a>.
</p>
6. 見出しの階層の欠落
// ❌ BAD: スクリーンリーダーがナビゲートできない
<div className="title">Welcome</div>
<div className="subtitle">Getting Started</div>
// ✅ GOOD: 適切な見出し
<h1>Welcome</h1>
<h2>Getting Started</h2>
ソクラテス式質問
答えを与える代わりに、これらの質問をしてください。
- キーボード: 「キーボードのみを使用してこのアクションを完了できますか?」
- フォーカス: 「ページを Tab キーで移動すると、自分がどこにいるかを確認できますか?」
- セマンティクス: 「スクリーンリーダーはこの要素について何をアナウンスしますか?」
- ラベル: 「プレースホルダーが消えた場合、ユーザーは入力を求められている内容をどのように知りますか?」
- 色: 「色覚異常の人がいても、この UI を理解できますか?」
- 代替テキスト: 「画像が読み込まれない場合、どのようなコンテキストが失われますか?」
アクセシビリティのテスト
手動テスト
- キーボードテスト: Tab キーのみを使用してページ全体をナビゲートする
- フォーカステスト: フォーカスがどこにあるかを常に確認できますか?
- ズームテスト: レイアウトは 200% ズームで崩れますか?
- スクリーンリーダー: VoiceOver (Mac) または NVDA (Windows) を試す
自動テスト
# テストファイル内
# パターン: React Testing Library 用の axe-core
import { axe } from 'jest-axe';
it('should have no a11y violations', async () => {
const { container } = render(<YourComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
ARIA リファレンス
一般的な ARIA 属性
| 属性 | ユースケース |
|---|---|
aria-label |
アイコンのみのボタンの名前を提供する |
aria-labelledby |
可視ラベルを持つ要素を指す |
aria-describedby |
説明 (エラーメッセージ) を指す |
aria-hidden="true" |
装飾的なアイコンをスクリーンリーダーから隠す |
aria-expanded |
ドロップダウン/アコーディオンの状態を示す |
aria-live |
動的なコンテンツの変更をアナウンスする |
role |
要素の目的を定義する (控えめに使用する) |
ARIA の第一法則
「悪い ARIA は、ARIA がないよりも悪い。」
最初にセマンティック HTML を使用してください。 HTML で必要なことを表現できない場合にのみ ARIA を使用してください。
スタック固有のガイダンス
React
// パターン: アクセシブルな名前を持つボタン
<button
onClick={handleAction}
aria-label="Close modal"
>
<XIcon aria-hidden="true" />
</button>
フォームエラーパターン
// パターン: 入力にリンクされたエラー
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
aria-describedby={error ? "email-error" : undefined}
aria-invalid={error ? "true" : undefined}
/>
{error && (
<span id="email-error" role="alert">
{error}
</span>
)}
注意すべき危険信号
| フラグ | 質問 |
|---|---|
<div onClick> |
「キーボードユーザーがこれをクリックしようとするとどうなりますか?」 |
outline: none |
「キーボードユーザーは自分がどこにいるかをどのように知りますか?」 |
| フォームラベルがない | 「スクリーンリーダーは、この入力が何のためのものかをどのように知りますか?」 |
| アイコンのみ |
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Accessibility Fundamentals Review
"Accessibility is not a feature, it's a requirement. If 15% of users can't use your app, you've failed 15% of users."
When to Apply
Activate this skill when:
- Reviewing JSX with buttons, links, or forms
- Seeing custom interactive components
- Forms with inputs and labels
- Navigation menus
- Modal dialogs
- Any user interaction code
The Accessibility Checklist
Must Have (Every Interactive Element)
- [ ] Keyboard accessible — All actions work with Tab + Enter/Space
- [ ] Focus visible — Clear visual indicator of focused element
- [ ] Semantic elements —
<button>not<div onClick> - [ ] Form labels — Every input has an associated
<label> - [ ] Alt text — Images have descriptive alt attributes
- [ ] Sufficient contrast — Text readable against background (4.5:1 ratio)
Should Have (Complex Interactions)
- [ ] ARIA labels — Icon-only buttons have
aria-label - [ ] Focus trapping — Modals trap focus until closed
- [ ] Skip links — "Skip to main content" for keyboard users
- [ ] Live regions — Dynamic content announced to screen readers
- [ ] Error messages — Linked to inputs with
aria-describedby
Never Do
- [ ] Rely on color alone — Color should not be the only indicator
- [ ] Remove focus outlines — Never
outline: nonewithout replacement - [ ] Use divs for buttons — Use semantic
<button>or<a> - [ ] Trap users — Always provide escape from modals/menus
Common Mistakes (Anti-Patterns)
1. Div as Button
// ❌ BAD: Not keyboard accessible, no semantics
<div onClick={handleClick} className="button">
Click me
</div>
// ✅ GOOD: Native button element
<button onClick={handleClick} className="button">
Click me
</button>
Why it matters: <div onClick> doesn't receive keyboard focus, doesn't respond to Enter/Space, and isn't announced as a button by screen readers.
2. Missing Form Labels
// ❌ BAD: Input has no label
<input type="email" placeholder="Email" />
// ✅ GOOD: Label linked to input
<label htmlFor="email">Email</label>
<input id="email" type="email" placeholder="example@email.com" />
// ✅ ALSO GOOD: Wrapping label
<label>
Email
<input type="email" />
</label>
3. Icon-Only Buttons
// ❌ BAD: No accessible name
<button onClick={handleDelete}>
<TrashIcon />
</button>
// ✅ GOOD: ARIA label for screen readers
<button onClick={handleDelete} aria-label="Delete item">
<TrashIcon aria-hidden="true" />
</button>
4. Removed Focus Styles
/* ❌ BAD: Focus invisible */
button:focus {
outline: none;
}
/* ✅ GOOD: Custom but visible focus */
button:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.6);
}
/* ✅ BEST: Use focus-visible */
button:focus-visible {
outline: 2px solid #4299e1;
outline-offset: 2px;
}
5. Non-Descriptive Link Text
// ❌ BAD: "Click here" tells screen reader nothing
<p>
To read our privacy policy, <a href="/privacy">click here</a>.
</p>
// ✅ GOOD: Link text describes destination
<p>
Read our <a href="/privacy">privacy policy</a>.
</p>
6. Missing Heading Hierarchy
// ❌ BAD: Screen reader can't navigate
<div className="title">Welcome</div>
<div className="subtitle">Getting Started</div>
// ✅ GOOD: Proper headings
<h1>Welcome</h1>
<h2>Getting Started</h2>
Socratic Questions
Ask these instead of giving answers:
- Keyboard: "Can you complete this action using only the keyboard?"
- Focus: "If I tab through the page, can I see where I am?"
- Semantics: "What does a screen reader announce for this element?"
- Labels: "If the placeholder disappears, how do users know what to enter?"
- Color: "If someone is colorblind, can they still understand this UI?"
- Alt Text: "If the image doesn't load, what context is lost?"
Testing Accessibility
Manual Testing
- Keyboard test: Navigate entire page with Tab only
- Focus test: Can you always see where focus is?
- Zoom test: Does layout break at 200% zoom?
- Screen reader: Try VoiceOver (Mac) or NVDA (Windows)
Automated Testing
# In your test file
# Pattern: axe-core for React Testing Library
import { axe } from 'jest-axe';
it('should have no a11y violations', async () => {
const { container } = render(<YourComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
ARIA Reference
Common ARIA Attributes
| Attribute | Use Case |
|---|---|
aria-label |
Provides name for icon-only buttons |
aria-labelledby |
Points to element with visible label |
aria-describedby |
Points to description (error messages) |
aria-hidden="true" |
Hides decorative icons from screen readers |
aria-expanded |
Indicates dropdown/accordion state |
aria-live |
Announces dynamic content changes |
role |
Defines element's purpose (use sparingly) |
The First Rule of ARIA
"No ARIA is better than bad ARIA."
Use semantic HTML first. Only use ARIA when HTML can't express what you need.
Stack-Specific Guidance
React
// Pattern: Button with accessible name
<button
onClick={handleAction}
aria-label="Close modal"
>
<XIcon aria-hidden="true" />
</button>
Form Error Pattern
// Pattern: Error linked to input
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
aria-describedby={error ? "email-error" : undefined}
aria-invalid={error ? "true" : undefined}
/>
{error && (
<span id="email-error" role="alert">
{error}
</span>
)}
Red Flags to Call Out
| Flag | Question |
|---|---|
<div onClick> |
"What happens when a keyboard user tries to click this?" |
outline: none |
"How does a keyboard user know where they are?" |
| No form labels | "How does a screen reader know what this input is for?" |
| Icon-only button | "What does a screen reader announce for this button?" |
| Color as only indicator | "What if someone is red-green colorblind?" |
tabIndex > 0 |
"This breaks natural tab order. Why is it needed?" |
Interview Connection
"I implemented accessibility best practices including semantic HTML, proper form labeling, and keyboard navigation, ensuring our app is usable by everyone."
STAR story material:
- "Identified accessibility issues with our form and fixed them..."
- "Implemented proper focus management in our modal component..."
- "Added screen reader support for our notification system..."
MCP Usage
Context7 - Framework Docs
Fetch: WAI-ARIA practices
Fetch: React accessibility documentation
Octocode - Real Examples
Search: "aria-label" + "button" patterns
Search: Modal focus trapping implementations
Resources
- WCAG 2.1 Guidelines (check Context7)
- Deque's axe-core for automated testing
- WebAIM color contrast checker