accessibility-compliance
Implement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support. Use when auditing accessibility, implementing ARIA patterns, building for screen readers, or ensuring inclusive user experiences.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o accessibility-compliance.zip https://jpskill.com/download/21037.zip && unzip -o accessibility-compliance.zip && rm accessibility-compliance.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/21037.zip -OutFile "$d\accessibility-compliance.zip"; Expand-Archive "$d\accessibility-compliance.zip" -DestinationPath $d -Force; ri "$d\accessibility-compliance.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
accessibility-compliance.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
accessibility-complianceフォルダができる - 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
- 同梱ファイル
- 4
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[Skill 名] accessibility-compliance
アクセシビリティ準拠
アクセシビリティの実装を習得し、障がいのあるユーザーを含むすべての人にとって使いやすい、インクルーシブな体験を創造します。
このスキルを使用する場面
- WCAG 2.2 レベル AA または AAA 準拠の実装
- スクリーンリーダーでアクセス可能なインターフェースの構築
- インタラクティブなコンポーネントへのキーボードナビゲーションの追加
- フォーカス管理とフォーカストラップの実装
- 適切なラベリングによるアクセス可能なフォームの作成
- 動作の軽減とハイコントラスト設定のサポート
- モバイルアクセシビリティ機能の構築 (iOS VoiceOver、Android TalkBack)
- アクセシビリティ監査の実施と違反の修正
主要な機能
1. WCAG 2.2 ガイドライン
- 知覚可能 (Perceivable): コンテンツはさまざまな方法で提示できる必要があります。
- 操作可能 (Operable): インターフェースはキーボードと支援技術でナビゲートできる必要があります。
- 理解可能 (Understandable): コンテンツと操作は明確である必要があります。
- 堅牢 (Robust): コンテンツは現在および将来の支援技術で機能する必要があります。
2. ARIA パターン
- ロール (Roles): 要素の目的を定義します (button, dialog, navigation)。
- ステート (States): 現在の状態を示します (expanded, selected, disabled)。
- プロパティ (Properties): 関係と追加情報について記述します (labelledby, describedby)。
- ライブリージョン (Live regions): 動的なコンテンツの変更をアナウンスします。
3. キーボードナビゲーション
- フォーカス順序とタブシーケンス
- フォーカスインジケーターと可視フォーカス状態
- キーボードショートカットとホットキー
- モーダルとダイアログのフォーカストラップ
4. スクリーンリーダーサポート
- セマンティックな HTML 構造
- 画像の代替テキスト
- 適切な見出し階層
- スキップリンクとランドマーク
5. モバイルアクセシビリティ
- タッチターゲットのサイズ設定 (最小 44x44dp)
- VoiceOver と TalkBack の互換性
- ジェスチャーの代替
- Dynamic Type のサポート
クイックリファレンス
WCAG 2.2 達成基準チェックリスト
| レベル | 基準 | 説明 |
|---|---|---|
| A | 1.1.1 | 非テキストコンテンツにはテキストによる代替があります |
| A | 1.3.1 | 情報と関係はプログラムで決定可能です |
| A | 2.1.1 | すべての機能はキーボードでアクセス可能です |
| A | 2.4.1 | メインコンテンツへのスキップメカニズム |
| AA | 1.4.3 | コントラスト比 4.5:1 (テキスト)、3:1 (大きなテキスト) |
| AA | 1.4.11 | 非テキストコントラスト 3:1 |
| AA | 2.4.7 | フォーカスは可視です |
| AA | 2.5.8 | ターゲットサイズ最小 24x24px (2.2 で新規) |
| AAA | 1.4.6 | 強化されたコントラスト 7:1 |
| AAA | 2.5.5 | ターゲットサイズ最小 44x44px |
主要なパターン
パターン 1: アクセス可能なボタン
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "primary" | "secondary";
isLoading?: boolean;
}
function AccessibleButton({
children,
variant = "primary",
isLoading = false,
disabled,
...props
}: ButtonProps) {
return (
<button
// Disable when loading
disabled={disabled || isLoading}
// Announce loading state to screen readers
aria-busy={isLoading}
// Describe the button's current state
aria-disabled={disabled || isLoading}
className={cn(
// Visible focus ring
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
// Minimum touch target size (44x44px)
"min-h-[44px] min-w-[44px]",
variant === "primary" && "bg-primary text-primary-foreground",
(disabled || isLoading) && "opacity-50 cursor-not-allowed",
)}
{...props}
>
{isLoading ? (
<>
<span className="sr-only">Loading</span>
<Spinner aria-hidden="true" />
</>
) : (
children
)}
</button>
);
}
パターン 2: アクセス可能なモーダルダイアログ
import * as React from "react";
import { FocusTrap } from "@headlessui/react";
interface DialogProps {
isOpen: boolean;
onClose: () => void;
title: string;
children: React.ReactNode;
}
function AccessibleDialog({ isOpen, onClose, title, children }: DialogProps) {
const titleId = React.useId();
const descriptionId = React.useId();
// Close on Escape key
React.useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape" && isOpen) {
onClose();
}
};
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}, [isOpen, onClose]);
// Prevent body scroll when open
React.useEffect(() => {
if (isOpen) {
document.body.style.overflow = "hidden";
}
return () => {
document.body.style.overflow = "";
};
}, [isOpen]);
if (!isOpen) return null;
return (
<div
role="dialog"
aria-modal="true"
aria-labelledby={titleId}
aria-describedby={descriptionId}
>
{/* Backdrop */}
<div
className="fixed inset-0 bg-black/50"
aria-hidden="true"
onClick={onClose}
/>
{/* Focus trap container */}
<FocusTrap>
<div className="fixed inset-0 flex items-center justify-center p-4">
<div className="bg-background rounded-lg shadow-lg max-w-md w-full p-6">
<h2 id={titleId} className="text-lg font-semibold">
{title}
</h2>
<div id={descriptionId}>{children}</div>
<button
onClick={onClose}
className="absolute top-4 right-4"
aria-label="Close dialog"
>
<X className="h-4 w-4" />
</button>
</div>
</div>
</FocusTrap>
</div>
);
}
パターン 3: アクセス可能なフォーム
function AccessibleForm() {
const [errors, setErrors] = React.useState<Record<string, string>>({});
return (
<form aria-describedby="form-errors" noValidate>
{/* Error su 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Accessibility Compliance
Master accessibility implementation to create inclusive experiences that work for everyone, including users with disabilities.
When to Use This Skill
- Implementing WCAG 2.2 Level AA or AAA compliance
- Building screen reader accessible interfaces
- Adding keyboard navigation to interactive components
- Implementing focus management and focus trapping
- Creating accessible forms with proper labeling
- Supporting reduced motion and high contrast preferences
- Building mobile accessibility features (iOS VoiceOver, Android TalkBack)
- Conducting accessibility audits and fixing violations
Core Capabilities
1. WCAG 2.2 Guidelines
- Perceivable: Content must be presentable in different ways
- Operable: Interface must be navigable with keyboard and assistive tech
- Understandable: Content and operation must be clear
- Robust: Content must work with current and future assistive technologies
2. ARIA Patterns
- Roles: Define element purpose (button, dialog, navigation)
- States: Indicate current condition (expanded, selected, disabled)
- Properties: Describe relationships and additional info (labelledby, describedby)
- Live regions: Announce dynamic content changes
3. Keyboard Navigation
- Focus order and tab sequence
- Focus indicators and visible focus states
- Keyboard shortcuts and hotkeys
- Focus trapping for modals and dialogs
4. Screen Reader Support
- Semantic HTML structure
- Alternative text for images
- Proper heading hierarchy
- Skip links and landmarks
5. Mobile Accessibility
- Touch target sizing (44x44dp minimum)
- VoiceOver and TalkBack compatibility
- Gesture alternatives
- Dynamic Type support
Quick Reference
WCAG 2.2 Success Criteria Checklist
| Level | Criterion | Description |
|---|---|---|
| A | 1.1.1 | Non-text content has text alternatives |
| A | 1.3.1 | Info and relationships programmatically determinable |
| A | 2.1.1 | All functionality keyboard accessible |
| A | 2.4.1 | Skip to main content mechanism |
| AA | 1.4.3 | Contrast ratio 4.5:1 (text), 3:1 (large text) |
| AA | 1.4.11 | Non-text contrast 3:1 |
| AA | 2.4.7 | Focus visible |
| AA | 2.5.8 | Target size minimum 24x24px (NEW in 2.2) |
| AAA | 1.4.6 | Enhanced contrast 7:1 |
| AAA | 2.5.5 | Target size minimum 44x44px |
Key Patterns
Pattern 1: Accessible Button
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "primary" | "secondary";
isLoading?: boolean;
}
function AccessibleButton({
children,
variant = "primary",
isLoading = false,
disabled,
...props
}: ButtonProps) {
return (
<button
// Disable when loading
disabled={disabled || isLoading}
// Announce loading state to screen readers
aria-busy={isLoading}
// Describe the button's current state
aria-disabled={disabled || isLoading}
className={cn(
// Visible focus ring
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
// Minimum touch target size (44x44px)
"min-h-[44px] min-w-[44px]",
variant === "primary" && "bg-primary text-primary-foreground",
(disabled || isLoading) && "opacity-50 cursor-not-allowed",
)}
{...props}
>
{isLoading ? (
<>
<span className="sr-only">Loading</span>
<Spinner aria-hidden="true" />
</>
) : (
children
)}
</button>
);
}
Pattern 2: Accessible Modal Dialog
import * as React from "react";
import { FocusTrap } from "@headlessui/react";
interface DialogProps {
isOpen: boolean;
onClose: () => void;
title: string;
children: React.ReactNode;
}
function AccessibleDialog({ isOpen, onClose, title, children }: DialogProps) {
const titleId = React.useId();
const descriptionId = React.useId();
// Close on Escape key
React.useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape" && isOpen) {
onClose();
}
};
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}, [isOpen, onClose]);
// Prevent body scroll when open
React.useEffect(() => {
if (isOpen) {
document.body.style.overflow = "hidden";
}
return () => {
document.body.style.overflow = "";
};
}, [isOpen]);
if (!isOpen) return null;
return (
<div
role="dialog"
aria-modal="true"
aria-labelledby={titleId}
aria-describedby={descriptionId}
>
{/* Backdrop */}
<div
className="fixed inset-0 bg-black/50"
aria-hidden="true"
onClick={onClose}
/>
{/* Focus trap container */}
<FocusTrap>
<div className="fixed inset-0 flex items-center justify-center p-4">
<div className="bg-background rounded-lg shadow-lg max-w-md w-full p-6">
<h2 id={titleId} className="text-lg font-semibold">
{title}
</h2>
<div id={descriptionId}>{children}</div>
<button
onClick={onClose}
className="absolute top-4 right-4"
aria-label="Close dialog"
>
<X className="h-4 w-4" />
</button>
</div>
</div>
</FocusTrap>
</div>
);
}
Pattern 3: Accessible Form
function AccessibleForm() {
const [errors, setErrors] = React.useState<Record<string, string>>({});
return (
<form aria-describedby="form-errors" noValidate>
{/* Error summary for screen readers */}
{Object.keys(errors).length > 0 && (
<div
id="form-errors"
role="alert"
aria-live="assertive"
className="bg-destructive/10 border border-destructive p-4 rounded-md mb-4"
>
<h2 className="font-semibold text-destructive">
Please fix the following errors:
</h2>
<ul className="list-disc list-inside mt-2">
{Object.entries(errors).map(([field, message]) => (
<li key={field}>
<a href={`#${field}`} className="underline">
{message}
</a>
</li>
))}
</ul>
</div>
)}
{/* Required field with error */}
<div className="space-y-2">
<label htmlFor="email" className="block font-medium">
Email address
<span aria-hidden="true" className="text-destructive ml-1">
*
</span>
<span className="sr-only">(required)</span>
</label>
<input
id="email"
name="email"
type="email"
required
aria-required="true"
aria-invalid={!!errors.email}
aria-describedby={errors.email ? "email-error" : "email-hint"}
className={cn(
"w-full px-3 py-2 border rounded-md",
errors.email && "border-destructive",
)}
/>
{errors.email ? (
<p id="email-error" className="text-sm text-destructive" role="alert">
{errors.email}
</p>
) : (
<p id="email-hint" className="text-sm text-muted-foreground">
We'll never share your email.
</p>
)}
</div>
<button type="submit" className="mt-4">
Submit
</button>
</form>
);
}
Pattern 4: Skip Navigation Link
function SkipLink() {
return (
<a
href="#main-content"
className={cn(
// Hidden by default, visible on focus
"sr-only focus:not-sr-only",
"focus:absolute focus:top-4 focus:left-4 focus:z-50",
"focus:bg-background focus:px-4 focus:py-2 focus:rounded-md",
"focus:ring-2 focus:ring-primary",
)}
>
Skip to main content
</a>
);
}
// In layout
function Layout({ children }) {
return (
<>
<SkipLink />
<header>...</header>
<nav aria-label="Main navigation">...</nav>
<main id="main-content" tabIndex={-1}>
{children}
</main>
<footer>...</footer>
</>
);
}
Pattern 5: Live Region for Announcements
function useAnnounce() {
const [message, setMessage] = React.useState("");
const announce = React.useCallback(
(text: string, priority: "polite" | "assertive" = "polite") => {
setMessage(""); // Clear first to ensure re-announcement
setTimeout(() => setMessage(text), 100);
},
[],
);
const Announcer = () => (
<div
role="status"
aria-live="polite"
aria-atomic="true"
className="sr-only"
>
{message}
</div>
);
return { announce, Announcer };
}
// Usage
function SearchResults({ results, isLoading }) {
const { announce, Announcer } = useAnnounce();
React.useEffect(() => {
if (!isLoading && results) {
announce(`${results.length} results found`);
}
}, [results, isLoading, announce]);
return (
<>
<Announcer />
<ul>{/* results */}</ul>
</>
);
}
Color Contrast Requirements
// Contrast ratio utilities
function getContrastRatio(foreground: string, background: string): number {
const fgLuminance = getLuminance(foreground);
const bgLuminance = getLuminance(background);
const lighter = Math.max(fgLuminance, bgLuminance);
const darker = Math.min(fgLuminance, bgLuminance);
return (lighter + 0.05) / (darker + 0.05);
}
// WCAG requirements
const CONTRAST_REQUIREMENTS = {
// Normal text (<18pt or <14pt bold)
normalText: {
AA: 4.5,
AAA: 7,
},
// Large text (>=18pt or >=14pt bold)
largeText: {
AA: 3,
AAA: 4.5,
},
// UI components and graphics
uiComponents: {
AA: 3,
},
};
Best Practices
- Use Semantic HTML: Prefer native elements over ARIA when possible
- Test with Real Users: Include people with disabilities in user testing
- Keyboard First: Design interactions to work without a mouse
- Don't Disable Focus Styles: Style them, don't remove them
- Provide Text Alternatives: All non-text content needs descriptions
- Support Zoom: Content should work at 200% zoom
- Announce Changes: Use live regions for dynamic content
- Respect Preferences: Honor prefers-reduced-motion and prefers-contrast
Common Issues
- Missing alt text: Images without descriptions
- Poor color contrast: Text hard to read against background
- Keyboard traps: Focus stuck in component
- Missing labels: Form inputs without associated labels
- Auto-playing media: Content that plays without user initiation
- Inaccessible custom controls: Recreating native functionality poorly
- Missing skip links: No way to bypass repetitive content
- Focus order issues: Tab order doesn't match visual order
Testing Tools
- Automated: axe DevTools, WAVE, Lighthouse
- Manual: VoiceOver (macOS/iOS), NVDA/JAWS (Windows), TalkBack (Android)
- Simulators: NoCoffee (vision), Silktide (various disabilities)
Resources
同梱ファイル
※ ZIPに含まれるファイル一覧。`SKILL.md` 本体に加え、参考資料・サンプル・スクリプトが入っている場合があります。
- 📄 SKILL.md (12,158 bytes)
- 📎 references/aria-patterns.md (13,204 bytes)
- 📎 references/mobile-accessibility.md (13,077 bytes)
- 📎 references/wcag-guidelines.md (14,206 bytes)