typo3-accessibility について
TYPO3 Accessibility は、TYPO3 v14 サイトを WCAG 2.2 AA に照らして監査・改善する技能です。公開前チェックリスト、監査手順、アクセシブルな Fluid テンプレート例を備え、自動検査の証拠と人による確認事項を区別します。
主な機能
- 01WCAG 2.2 AA 公開前チェックリスト
- 02axe-core による監査手順
- 03キーボード操作とセマンティクスの確認
- 04アクセシブルな Fluid テンプレート例
- 05監査根拠と追加確認事項の報告
活用シーン
- 01公開前のアクセシビリティ確認
- 02レンダリング済み TYPO3 ページの監査
- 03キーボード操作とフォームの確認
- 04監査結果と未確認事項の記録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dirnbauer/ webconsulting-skills --skill typo3-accessibilityインストール後、Claude Code で/typo3-accessibilityを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/03-php-accessibility-middleware-and-helpers.md04-javascript-accessible-widgets.md05-css-focus-and-contrast-essentials.md06-typo3-specific-configuration.md07-testing-and-tools.md08-accessibility-extensions.md09-wcag-2-2-quick-reference.md10-anti-patterns-flag-these-in-reviews.mdcredits-and-attribution.mdfull-guide.mdrelated-skills.mdv14-only-accessibility-changes.mdscripts/wcag22_audit.cjs詳細
TYPO3 アクセシビリティ(WCAG 2.2 AA)
互換性: TYPO3 v14.x のみに対応しています。このコレクションの対象に旧バージョンのコアは含まれません。
TYPO3 API を優先: カスタムマークアップを追加する前に、必ず TYPO3 の組み込み API、Fluid ViewHelper、コア機能を使用してください。メソッドが TYPO3 v14 に存在することを確認してください。
TypoScript より PHP と JS を優先: このスキルでは、PHP ミドルウェア、Fluid パーシャル、バニラ JavaScript のソリューションを提供します。TypoScript の例は使用せず、PHP ベースの手法を使用してください。
1. アクセシビリティチェックリスト(公開前の確認項目)
デプロイの前に、このチェックリストを確認してください。項目を修正したらチェックを付けます。
セマンティックな構造
- すべてのページに
<h1>がちょうど 1 つある - 見出しの階層が順番になっている(
h1>h2>h3、飛ばさない) - ランドマーク要素を使用している:
<main>、<nav>、<header>、<footer>、<aside> - スキップリンクが最初にフォーカス可能な要素になっている
-
<html lang="...">がページの言語と一致している - コンテンツ内で言語が変わる箇所では、包含要素に
lang属性を使用している
画像とメディア
- すべての
<img>にalt属性がある(装飾目的の場合はalt="") - すべての
<img>に明示的なwidthとheightがある(CLS を防止) - 複雑な画像(グラフ、インフォグラフィック)に長い説明がある
- 動画にキャプション/字幕がある
- 音声コンテンツに文字起こしがある
- 音声付きのメディアを自動再生しない
色とコントラスト
- テキストのコントラスト比が 4.5:1 以上(通常のテキスト)/3:1 以上(大きなテキスト:24px 以上/太字で 18.66px 以上)
- UI コンポーネントとグラフィックオブジェクトのコントラスト比が 3:1 以上
- 色だけで情報を伝えない(アイコン、テキスト、またはパターンを追加する)
- ダークモード(実装している場合)でもコントラスト比を維持している
キーボード操作とフォーカス
- すべてのインタラクティブ要素に Tab キーで移動できる
- フォーカス順が視覚的な順序と一致している
- すべてのインタラクティブ要素に視認できるフォーカスインジケーターがある(
:focus-visible) - モーダルを除き、フォーカストラップがない(モーダルでは適切にトラップする必要があります)
- Escape キーでモーダル/オーバーレイが閉じ、トリガーにフォーカスが戻る
- カスタムウィジェットに適切なキーボードハンドラーがある
フォーム
- すべての入力にプログラムで関連付けられた
<label>がある(明示的なfor/id、またはラップで関連付ける) - プレースホルダーを唯一のラベルとして使用していない
- 必須フィールドが視覚的に示され、
required属性も指定されている - エラーメッセージが
aria-describedbyとaria-invalidで入力に関連付けられている - フォームグループで
<fieldset>と<legend>を使用している - 入力に適切な
type属性とautocomplete属性がある
ARIA と動的コンテンツ
- アイコンのみのボタンに
aria-labelがある - 装飾アイコンに
aria-hidden="true"がある - 動的な更新で
aria-live="polite"またはrole="status"を使用している - エラー通知で
role="alert"を使用している - アクティブなナビゲーションリンクに
aria-current="page"がある - 展開可能な要素で
aria-expandedを使用している
モーションとインタラクション
-
prefers-reduced-motionに対応している(CSS と JS) - コンテンツが 1 秒あたり 3 回を超えて点滅しない
- タッチターゲットが WCAG 2.2 AA 2.5.8 の要件を満たしている(最小 24×24 CSS ピクセル)。実現可能な場合は、より快適な基準として 44×44 を使用する
- ビューポートのメタタグで
user-scalable=noを設定していない
TYPO3 固有の項目
- バックエンド:File List のすべての画像で代替テキスト欄が入力されている
- バックエンド:コンテンツ要素に内容を表すヘッダーがある(非表示にする場合は
header_layout = 100) - バックエンド:ページプロパティに適切な
<title>とdescriptionが設定されている - Fluid テンプレートで
<f:link.page>/<f:link.typolink>を使用している(手動でhrefを指定した<a>ではなく) - Content Block/Content Element のテンプレートが、以下のアクセシブルなパターンに従っている
2. WCAG 2.2 適合性監査のワークフロー
WCAG 2.2 の監査を依頼された場合は、作業を引き渡す前にエージェントが実施できることを行います。
- 監査対象の URL、言語、ビューポート、フォーム、ダイアログ、メニュー、メディア、ダウンロード、サードパーティの埋め込みコンテンツを特定します。
- axe-core の WCAG 2.0/2.1/2.2 A/AA タグを指定して、レンダリングされたページに対し
scripts/wcag22_audit.cjsを実行します。 - 自動検出されたすべての違反と
incomplete項目を確認し、修正するか、内容を記録します。監査スクリプトは、可能な場合、color-contrastのincompleteノードのコントラストを計算します。対応をエスカレーションする前に、その結果を利用してください。未解決のincompleteを合格として扱わないでください。 - セマンティックな構造、ページの言語、ランドマーク、
<h1>が1つであること、見出しの順序、スキップリンク、画像のalt、画像の寸法、ビューポートのズーム、フッター/ヘッダーのナビゲーション、フォーカス可能性、ターゲットサイズの候補、インラインテキストリンクに関するターゲットサイズの例外を確認します。 - 可能な場合は、実際に Tab キーで移動してキーボード操作の順序を確認します。明らかなテンプレート/コンポーネントの不具合は、すぐに修正します。
- 次の2つのセクションを含む監査レポートを作成します。
- エージェントが完了した検証結果: コマンド、URL、ビューポート、ツールのバージョン、違反、修正、残存する技術的リスク。
- 人間/ユーザーのみが行うフォローアップ: スクリーンリーダーでの確認、法的声明の承認、該当する場合に限り、特定デバイスのみで行う作業、サードパーティ/PDF/メディア、ユーザーテストに関する作業。
適合性監査を依頼された場合は、Testing & Tools の詳細な手順に従ってください。自動テストの実行に成功しても、WCAG 適合性を主張できるわけではありません。自動化とコード検査で確認できる範囲についての証拠となります。
3. Fluid テンプレートのパターン
3.1 ランドマークを使用したページレイアウト
<f:render section="Main" />
<f:layout name="Default" />
<f:section name="Main">
<a href="#main-content" class="skip-link">
<f:translate key="LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:skip_to_content" />
</a>
<header>
<f:cObject typoscriptObjectPath="lib.mainNavigation" />
</header>
<main id="main-content">
<f:render section="Content" />
</main>
<footer>
<nav aria-label="{f:translate(key: 'LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:nav.footer')}">
<f:cObject typoscriptObjectPath="lib.footerNavigation" />
</nav>
</footer>
</f:section>
3.2 スキップリンクの CSS
.skip-link {
position: absolute;
top: -100%;
left: 0;
z-index: 10000;
padding: 0.75rem 1.5rem;
background: var(--color-primary, #2563eb);
color: var(--color-on-primary, #fff);
font-weight: 600;
text-decoration: none;
}
.skip-link:focus {
top: 0;
}
3.3 アクセシブルな画像のレンダリング
<f:if condition="{image}">
<figure>
<f:image
image="{image}"
alt="{image.alternative}"
title="{image.title}"
width="{dimensions.width}"
height="{dimensions.height}"
loading="{f:if(condition: lazyLoad, then: 'lazy', else: 'eager')}"
additionalAttributes="{decoding: 'async'}"
/>
<f:if condition="{image.description}">
<figcaption>{image.description}</figcaption>
</f:if>
</figure>
</f:if>
装飾用画像の場合(情報としての価値がない場合):
<f:image image="{image}" alt="" />
3.4 アクセシブルなコンテンツ要素のラッパー
<f:if condition="{data.header} && {data.header_layout} != '100'">
<f:switch expression="{data.header_layout}">
<f:case value="1"><h1>{data.header}</h1></f:case>
<f:case value="2"><h2>{data.header}</h2></f:case>
<f:case value="3"><h3>{data.header}</h3></f:case>
<f:case value="4"><h4>{data.header}</h4></f:case>
<f:case value="5"><h5>{data.header}</h5></f:case>
<f:defaultCase><h2>{data.header}</h2></f:defaultCase>
</f:switch>
</f:if>
3.5 アクセシブルなナビゲーションの部分テンプレート
<nav aria-label="{f:translate(key: 'LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:nav.main')}">
<ul role="list">
<f:for each="{menu}" as="item">
<li>
<f:if condition="{item.active}">
<f:then>
<a href="{item.link}" aria-current="page">{item.title}</a>
</f:then>
<f:else>
<a href="{item.link}">{item.title}</a>
</f:else>
</f:if>
<f:if condition="{item.children}">
<ul>
<f:for each="{item.children}" as="child">
<li>
<a href="{child.link}"
{f:if(condition: child.active, then: 'aria-current="page"')}>
{child.title}
</a>
</li>
</f:for>
</ul>
</f:if>
</li>
</f:for>
</ul>
</nav>
3.6 アクセシブルなアコーディオン(コンテンツブロック/カスタム CE)
<div class="accordion" data-accordion>
<f:for each="{items}" as="item" iteration="iter">
<div class="accordion__item">
<div role="heading" aria-level="{f:if(condition: headingLevel, then: headingLevel, else: '3')}">
<button
type="button"
class="accordion__trigger"
aria-expanded="false"
aria-controls="accordion-panel-{data.uid}-{iter.index}"
id="accordion-header-{data.uid}-{iter.index}"
data-accordion-trigger
>
{item.header}
</button>
</div>
<div
id="accordion-panel-{data.uid}-{iter.index}"
role="region"
aria-labelledby="accordion-header-{data.uid}-{iter.index}"
class="accordion__panel"
hidden
>
<f:format.html>{item.bodytext}</f:format.html>
</div>
</div>
</f:for>
</div>
3.7 アクセシブルなタブコンポーネント
<div class="tabs" data-tabs>
<div role="tablist" aria-label="{f:translate(key: 'tabs.label')}">
<f:for each="{items}" as="item" iteration="iter">
<button
type="button"
role="tab"
id="tab-{data.uid}-{iter.index}"
aria-controls="tabpanel-{data.uid}-{iter.index}"
aria-selected="{f:if(condition: iter.isFirst, then: 'true', else: 'false')}"
tabindex="{f:if(condition: iter.isFirst, then: '0', else: '-1')}"
>
{item.header}
</button>
</f:for>
</div>
<f:for each="{items}" as="item" iteration="iter">
<div
role="tabpanel"
id="tabpanel-{data.uid}-{iter.index}"
aria-labelledby="tab-{data.uid}-{iter.index}"
tabindex="0"
{f:if(condition: iter.isFirst, then: '', else: 'hidden')}
>
<f:format.html>{item.bodytext}</f:format.html>
</div>
</f:for>
</div>
詳細なリファレンス
詳細な例、長いテンプレート、トラブルシューティング用の一覧表、付録、または上記に含まれていないセクションが必要な場合は、完全ガイドをお読みください。範囲の限られたタスクでは、このファイルを読み込まず、スキルが段階的に情報を開示するようにしてください。