ワンクリックで
web-accessibility
Webアクセシビリティ対応ガイド。WCAG 2.1準拠、セマンティックHTML、ARIA属性、キーボード操作、スクリーンリーダー対応など、誰もが使えるWebアプリケーション構築のベストプラクティス。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Webアクセシビリティ対応ガイド。WCAG 2.1準拠、セマンティックHTML、ARIA属性、キーボード操作、スクリーンリーダー対応など、誰もが使えるWebアプリケーション構築のベストプラクティス。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
コンピュータサイエンスの基礎知識を網羅的にカバー。ハードウェアの仕組みからデータ表現、アルゴリズム、データ構造、計算理論、プログラミングパラダイム、ソフトウェアエンジニアリング基礎まで、エンジニアに必要な全てのCS基礎知識を体系的に解説。
Fundamentals of modern web development. Framework selection (React, Vue, Next.js), project architecture, state management, routing, build tools, and CSS strategy best practices.
A comprehensive guide covering the fundamentals of computer science. From hardware internals and data representation to algorithms, data structures, computation theory, programming paradigms, and software engineering basics — a systematic guide to all the CS foundations every engineer needs.
DJテクニック(Rekordbox 7.2.7)と楽曲制作(Ableton Live 12 Suite)を体系的に学べる包括的なガイド。基礎音楽理論から応用テクニック、キャリア構築まで、DJ・音楽プロデューサーに必要な全スキルをカバー。
CLIツール開発ガイド。Node.js(Commander、Inquirer)、Python(Click、Typer)、Go(Cobra)、引数パース、インタラクティブUI、アーキテクチャ設計、テスト、配布方法など、プロフェッショナルなCLIツール開発のベストプラクティス。
スクリプト開発ガイド。Shell、Python、Node.jsスクリプト、自動化、バッチ処理、環境変数管理など、効率的なスクリプト開発のベストプラクティス。
| name | web-accessibility |
| description | Webアクセシビリティ対応ガイド。WCAG 2.1準拠、セマンティックHTML、ARIA属性、キーボード操作、スクリーンリーダー対応など、誰もが使えるWebアプリケーション構築のベストプラクティス。 |
このSkillは、Webアクセシビリティをカバーします:
このガイドで学べること: WCAG準拠方法、セマンティックHTML、ARIA属性、キーボード操作、アクセシビリティテスト 公式で確認すべきこと: 最新のWCAG基準、ブラウザサポート、支援技術の動向
WCAG 2.1 Guidelines - W3Cアクセシビリティガイドライン
WAI-ARIA Authoring Practices - ARIAパターンガイド
MDN Accessibility - MDNアクセシビリティガイド
Apple Accessibility - iOSアクセシビリティ
以下の完全ガイドで、実践的なアクセシビリティ実装を学べます:
26,000文字 | React 18.2.0+ | Next.js 14.0+
27,500文字 | WAI-ARIA 1.2 | React 18.2.0+
28,000文字 | axe-core 4.8.0+ | Playwright 1.40.0+
合計: 81,500文字 | 3ガイド
| レベル | 説明 | 要件 |
|---|---|---|
| A | 最低限 | 基本的なアクセシビリティ |
| AA | 推奨(法的要件の場合多い) | 中程度のアクセシビリティ |
| AAA | 最高レベル | 高度なアクセシビリティ |
<!-- ❌ 悪い例 -->
<div onclick="navigate()">Home</div>
<div onclick="submit()">Submit</div>
<!-- ✅ 良い例 -->
<nav>
<a href="/">Home</a>
</nav>
<button type="submit">Submit</button>
<header>
<nav aria-label="Main navigation">
<!-- ナビゲーション -->
</nav>
</header>
<main>
<article>
<h1>Article Title</h1>
<section>
<h2>Section Title</h2>
<!-- コンテンツ -->
</section>
</article>
<aside>
<!-- サイドバー -->
</aside>
</main>
<footer>
<!-- フッター -->
</footer>
<!-- ✅ 良い例(階層的) -->
<h1>Page Title</h1>
<h2>Section 1</h2>
<h3>Subsection 1.1</h3>
<h2>Section 2</h2>
<!-- ❌ 悪い例(階層がスキップ) -->
<h1>Page Title</h1>
<h3>Section 1</h3> <!-- h2をスキップ -->
// アイコンボタン
<button aria-label="Close">
<XIcon />
</button>
// 複数ナビゲーション
<nav aria-label="Main navigation">
{/* ... */}
</nav>
<nav aria-label="Footer navigation">
{/* ... */}
</nav>
// aria-labelledby(既存の要素を参照)
<div role="dialog" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirmation</h2>
{/* ... */}
</div>
<input
type="email"
aria-describedby="email-help"
/>
<span id="email-help">
We'll never share your email.
</span>
// リアルタイム通知
<div aria-live="polite" aria-atomic="true">
{status}
</div>
// 緊急通知
<div aria-live="assertive">
{error}
</div>
// カスタムコンポーネント
<div role="button" tabIndex={0} onClick={handleClick} onKeyDown={handleKeyDown}>
Click me
</div>
// リスト
<ul role="list">
<li role="listitem">Item 1</li>
<li role="listitem">Item 2</li>
</ul>
// ✅ ネイティブ要素(自動的にフォーカス可能)
<button>Click</button>
<a href="/">Link</a>
<input type="text" />
// ✅ カスタム要素(tabIndexを追加)
<div
role="button"
tabIndex={0}
onClick={handleClick}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
handleClick()
}
}}
>
Custom Button
</div>
import { useEffect, useRef } from 'react'
function Modal({ onClose }: { onClose: () => void }) {
const modalRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
onClose()
}
// Tab キーでフォーカストラップ
if (e.key === 'Tab') {
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
)
if (!focusableElements) return
const firstElement = focusableElements[0] as HTMLElement
const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement
if (e.shiftKey && document.activeElement === firstElement) {
lastElement.focus()
e.preventDefault()
} else if (!e.shiftKey && document.activeElement === lastElement) {
firstElement.focus()
e.preventDefault()
}
}
}
document.addEventListener('keydown', handleKeyDown)
return () => document.removeEventListener('keydown', handleKeyDown)
}, [onClose])
return (
<div
ref={modalRef}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
>
<h2 id="modal-title">Modal Title</h2>
<button onClick={onClose}>Close</button>
</div>
)
}
// app/layout.tsx
export default function RootLayout({ children }) {
return (
<html>
<body>
<a href="#main" className="skip-link">
Skip to main content
</a>
<nav>{/* ナビゲーション */}</nav>
<main id="main">{children}</main>
</body>
</html>
)
}
// globals.css
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #000;
color: #fff;
padding: 8px;
z-index: 100;
}
.skip-link:focus {
top: 0;
}
/* ❌ 悪い例(コントラスト不足) */
.text {
color: #999; /* 3:1 */
background: #fff;
}
/* ✅ 良い例 */
.text {
color: #666; /* 5.74:1 */
background: #fff;
}
/* ✅ 視認性の高いフォーカススタイル */
button:focus-visible {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
/* ❌ 悪い例 */
button:focus {
outline: none; /* フォーカスが見えない */
}
interface ButtonProps {
children: React.ReactNode
onClick: () => void
disabled?: boolean
'aria-label'?: string
}
export function Button({ children, onClick, disabled, 'aria-label': ariaLabel }: ButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled}
aria-label={ariaLabel}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
>
{children}
</button>
)
}
export function ContactForm() {
return (
<form>
<div>
<label htmlFor="name">Name *</label>
<input
id="name"
type="text"
required
aria-required="true"
/>
</div>
<div>
<label htmlFor="email">Email *</label>
<input
id="email"
type="email"
required
aria-required="true"
aria-describedby="email-help"
/>
<span id="email-help" className="text-sm text-gray-600">
We'll never share your email.
</span>
</div>
<div role="group" aria-labelledby="contact-method">
<span id="contact-method">Preferred contact method</span>
<label>
<input type="radio" name="contact" value="email" />
Email
</label>
<label>
<input type="radio" name="contact" value="phone" />
Phone
</label>
</div>
<button type="submit">Submit</button>
</form>
)
}
'use client'
import { useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
interface ModalProps {
isOpen: boolean
onClose: () => void
title: string
children: React.ReactNode
}
export function Modal({ isOpen, onClose, title, children }: ModalProps) {
const modalRef = useRef<HTMLDivElement>(null)
const previousActiveElement = useRef<HTMLElement | null>(null)
useEffect(() => {
if (isOpen) {
previousActiveElement.current = document.activeElement as HTMLElement
modalRef.current?.focus()
} else {
previousActiveElement.current?.focus()
}
}, [isOpen])
if (!isOpen) return null
return createPortal(
<div
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center"
onClick={onClose}
>
<div
ref={modalRef}
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
tabIndex={-1}
className="bg-white p-6 rounded-lg max-w-md w-full"
onClick={(e) => e.stopPropagation()}
>
<h2 id="modal-title" className="text-2xl font-bold mb-4">
{title}
</h2>
{children}
<button
onClick={onClose}
aria-label="Close modal"
className="mt-4 px-4 py-2 bg-gray-200 rounded"
>
Close
</button>
</div>
</div>,
document.body
)
}
pnpm add -D @axe-core/react
// app/layout.tsx(開発環境のみ)
if (process.env.NODE_ENV !== 'production') {
const axe = require('@axe-core/react')
const React = require('react')
const ReactDOM = require('react-dom')
axe(React, ReactDOM, 1000)
}
アクセシビリティ監査
このページのアクセシビリティを確認してください。
WCAG AA基準に準拠しているか確認してください。
ARIA属性追加
このコンポーネントに適切なARIA属性を追加してください。
スクリーンリーダーで読み上げられるようにしてください。
Last updated: 2025-12-26