Article

WebアクセシビリティJIS規格対応チェックリスト:見直しポイントまとめ

高田晃太郎
WebアクセシビリティJIS規格対応チェックリスト:見直しポイントまとめ

世界では人口の約16%が障害のある人々で構成されるとWHOは報告しており¹、WebAIMのThe WebAIM Millionでは毎年、一般サイトの約96%が検出可能なWCAG違反を含む現実が示されています²。国内でも公共分野を中心にJIS X 8341-3への準拠が常識化し、民間でも入札・グローバル展開・SEOを意識した対応が広がっています。現場では、後工程での修正が設計段階の数倍以上のコストに膨らむケースが繰り返し報告されます。だからこそ、実装者が迷わず適用できる「Webアクセシビリティ チェックリスト」を軸にした進め方が、投資対効果の最大化に直結します。

この記事ではJIS X 8341-3:2016をベースに³、最新のWCAG 2.1/2.2の観点も補いながら、AA到達に必要な見直しポイントをコードと運用プロセスで具体化します。単なる概念の列挙ではなく、達成基準をソースコードと試験計画に落とし込むことで、リグレッションに強いチーム体制をつくることを狙います。特に2.2で追加・強化されたターゲットサイズ、ドラッグ操作の代替、フォーカスの見え方・被覆防止、ヘルプの一貫性、冗長入力の回避、認証のしやすさといったモバイル・タッチUI関連の配慮は、事故を減らせます¹⁰ ¹¹ ¹² ¹³ ¹⁴ ¹⁵。

JIS X 8341-3の位置づけと適合主張の前提を固める

まず理解すべきは、JIS X 8341-3:2016がWCAG 2.0を基礎にしている点です³。国内では依然としてJIS準拠の対外発信が求められる一方で、実装要件はモバイルやSPAの普及に合わせてWCAG 2.1 AA、さらに2.2の該当項目(例:2.5.7 ドラッグ操作の代替、2.5.8 ターゲットサイズ、2.4.11/2.4.12 フォーカスの可視性・被覆防止、3.2.6 ヘルプの一貫性、3.3.7 冗長入力の回避、3.3.8 認証のしやすさ)までを組み入れると実務上の抜けが減ります¹⁰ ¹¹ ¹² ¹³ ¹⁴ ¹⁵。適合を主張する場合は、ウェブページ一式の範囲、達成等級、試験方法、対象ブラウザ・支援技術の前提、そして試験結果公開を明確にしておく必要があります。ここが曖昧だと調達・監査・改修フェーズで齟齬が発生します。

実務では、テンプレート単位の代表ページを選定し、UIパターンの網羅率を担保します。ナビゲーション、詳細ページ、検索・一覧・フォーム、モーダル・トーストなどのインタラクション、動画・ダウンロードなどを横断し、PCとモバイルの両方でキーボードとタッチの操作性を検証します。KPIは、例としてLighthouse Accessibilityスコア90以上、axe-coreのCritical/Serious違反ゼロ、コントラスト違反ゼロ、JIS AA達成率95%以上を起点にし、重要導線では実効的なユーザーテストを合わせます。社外への掲載用に、対象範囲と達成状況、既知の例外、改善計画を含む試験結果ページを用意しておくと、次回改訂時の比較と説明が容易です。

見出し構造とスキップリンクで骨格を整える

骨格が崩れているサイトは、どれだけ装飾を整えても読み上げやキーボードナビゲーションで破綻します。ページには唯一のh1を置き、h2以降は見出しレベルを飛ばさず順序立てます。ランドマーク領域を適切に付け、キーボード利用者がスキップリンクで主要領域へ直接移動できるようにします。視覚的に非表示のリンクはフォーカス時に確実に可視化してください⁴。

<!-- Code 1: スキップリンクと見出し・ランドマーク -->
<a href="#main" class="skip-link">メインコンテンツへスキップ</a>
<header role="banner">...</header>
<nav aria-label="主ナビゲーション">...</nav>
<main id="main" role="main">
  <h1>製品一覧</h1>
  <h2>カテゴリA</h2>
  <h3>新着アイテム</h3>
</main>
<footer role="contentinfo">...</footer>
/* Code 2: スキップリンクの可視化とフォーカス */
.skip-link {
  position: absolute; left: -999px; top: auto;
}
.skip-link:focus {
  left: 1rem; top: 1rem; z-index: 1000;
  background: #fff; color: #000; padding: .5rem 1rem; outline: 3px solid #1a73e8;
}

画像の代替テキストは目的で書き分ける

代替テキストは画像の「見た目の説明」ではなく「機能や意図の伝達」を目的にします。装飾画像は空のaltで読み上げから除外し、リンク画像はリンク先の目的を示し、複雑な情報は周辺テキストや説明要素に委ねます。チャートや図版はaria-describedbyで詳細説明に結びつけると、画面幅に依存しない堅牢性が生まれます⁵。

<!-- Code 3: 画像のパターン -->
<!-- 装飾: 空alt -->
<img src="/img/divider.png" alt="" role="presentation">

<!-- リンク目的を伝える -->
<a href="/pricing">
  <img src="/img/cta.png" alt="料金プランを見る">
</a>

<!-- 図版の詳細説明 -->
<figure>
  <img src="/img/chart.png" alt="四半期の売上推移の折れ線グラフ" aria-describedby="chart-desc">
  <figcaption id="chart-desc">2024Q1からQ4で売上は20%増加。Q3にプロモーションの効果が顕著。</figcaption>
</figure>

操作可能性の核心:キーボード、フォーカス、フォーム

JIS/WCAGの致命的違反は、キーボード操作の欠落で起こります。すべての機能はキーボードのみで実行でき、フォーカスの順序は視覚順と論理的に一致し、フォーカスの見え方は常に十分なコントラストで可視化されている必要があります⁷。2.2ではフォーカスインジケータの可視性要件が強化され(Focus Appearance)¹¹、さらにステッキーヘッダー等でフォーカスが隠れないこと(Focus Not Obscured)¹¹が求められます。タブ移動中にフォーカスを消すCSSは避け、モーダルやダイアログではフォーカストラップを適切に実装し、閉じた後にトリガーへフォーカスを戻します。繰り返し現れるヘッダーやフッターのリンクは順序を変えないことで、ユーザーの学習コストを下げられます。

/* Code 4: フォーカスの可視化強化とコントラスト配慮 */
:focus { outline: none; } /* 悪手: 禁止に近い */

:where(a, button, [role="button"], input, select, textarea):focus-visible {
  outline: 3px solid #0a7; outline-offset: 2px; /* 目安としてコントラスト3:1以上と十分な太さを確保(WCAG 2.2) */
}

/* カスタムUIのフォーカスリング */
.custom-card[tabindex="0"]:focus-visible {
  box-shadow: 0 0 0 4px rgba(10,119,102,.4);
}

フォームは、ラベルと入力の関連付け、必須項目の明示、エラーの特定と提案、説明文のプログラム的関連が鍵です⁶。プレースホルダは説明ではなく補助として使い、入力中でも消えない説明はaria-describedbyで結びます。エラーはテキストで説明し、色だけに依存しない表示にします。送信後のエラーまとめと、エラー領域へのフォーカス移動は、支援技術とキーボード利用者の双方に有効です。あわせて2.2の冗長入力の回避(Redundant Entry)¹³に留意し、再入力を強いない設計(自動入力、既知値のプレフィル、autocomplete属性の活用)を進めます。認証では、画像選択やなぞなぞのような認知負荷の高い手段に依存せず、パスワードマネージャー・コピー&ペースト・パスキー等を妨げない(Accessible Authentication)¹⁴ことが推奨されます。

<!-- Code 5: ラベル、説明、エラーの関連付け(autocompleteを追加) -->
<form novalidate aria-describedby="form-help">
  <p id="form-help">* は必須項目です。電話番号はハイフンなしの半角数字。</p>
  <div>
    <label for="email">メールアドレス</label>
    <input id="email" name="email" type="email" autocomplete="email"
           aria-describedby="email-hint email-err" required>
    <div id="email-hint">例: user@example.com</div>
    <div id="email-err" class="error" role="alert" aria-live="assertive" hidden>有効なメールアドレスを入力してください</div>
  </div>
  <button type="submit">送信</button>
</form>
// Code 6: エラー時に最初のエラーへフォーカス
function focusFirstError() {
  const err = document.querySelector('.error:not([hidden])');
  if (err) err.setAttribute('tabindex', '-1'), err.focus();
}

キーボードトラップの回避とショートカットの安全性

モーダルやメニュー、カスタムコンポーネントでは、Tab/Shift+Tabで内部を循環し、Escapeで確実に閉じる実装が必要です。シングルキーショートカットは無効化や変更手段を提供し、スクリーンリーダーのキー競合を避けます。ドラッグ操作は代替手段を提供し、マウスやタッチに限定しないようにします¹⁰。さらに2.2のターゲットサイズ(Minimum)¹²により、誤タップを避けるための領域確保がより明確になりました。一般に24×24 CSSピクセル以上を目安に、密集配置を避け、十分なタップ領域を確保します。

// Code 7: シンプルなフォーカストラップ
function trapFocus(container) {
  const focusables = container.querySelectorAll('a, button, input, [tabindex="0"]');
  function onKey(e) {
    if (e.key === 'Escape') { container.close(); return; }
    if (e.key !== 'Tab') return;
    const first = focusables[0];
    const last = focusables[focusables.length - 1];
    if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
    else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
  }
  container.addEventListener('keydown', onKey);
}

知覚可能性の実装要点:コントラスト、メディア、リフロー

テキストは通常サイズで4.5:1、18ptまたは太字14pt相当以上は3:1以上のコントラストが必要です⁸。アイコンと重要なUI部品も視覚上の境界が十分であることが求められます。最近のデザインシステムではトークン段階でコントラストを担保すると、局所対応のばらつきが減ります。カラーモード切り替え時にも比率が崩れないよう、前景・背景の組み合わせを事前に網羅テストしておくと安全です。色だけに依存した状態表現は避け、テキストやアイコン形状を併用します。

/* Code 8: デザイントークンでコントラストを担保 */
:root { --fg: #111; --bg: #fff; --accent: #0a7; }
[data-theme="dark"] { --fg: #f5f5f5; --bg: #111; --accent: #4bd; }
.button {
  color: var(--fg); background: var(--accent);
  /* デザイン審査でcontrast(var(--accent), var(--fg)) ≥ 4.5:1 をレビュー */
}

動画と音声は、同期字幕と音声解説、静的な代替としてのトランスクリプトを提供します。自動再生は音声を伴わないか、少なくともユーザーが音量を制御できるUIを提供します。過度の点滅や閃光は避け、アニメーションはユーザーの視覚的好みに従って抑制します。CSSのprefers-reduced-motionメディアクエリに応じて動きを弱める実装は、眩暈を引き起こすユーザーを守ります。

<!-- Code 9: 字幕・トランスクリプト・音量制御 -->
<video controls preload="metadata" aria-describedby="v-desc">
  <source src="/movie/intro.mp4" type="video/mp4">
  <track kind="captions" src="/movie/intro_ja.vtt" srclang="ja" label="日本語" default>
  <track kind="captions" src="/movie/intro_en.vtt" srclang="en" label="English">
</video>
<p id="v-desc"><a href="/movie/intro_transcript">テキスト版のトランスクリプトを読む</a></p>
/* Code 10: 動きを抑制 */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

ズームとリフローに関しては、400%拡大時や320CSSピクセル相当のビューポートでも情報や機能が失われないことが重要です⁹。固定幅のコンテナやビューポート単位の文字サイズ固定は避け、折返しに耐えるレイアウトを選択します。横スクロールが不可避な場合は表やコードなど限定的な要素に留め、主要導線は常に縦方向のスクロールで完結させます⁹。

SPA/デザインシステムでのJIS対応:名前・役割・値を死守する

カスタムUIが増えるほど、プログラムで判断可能な名前・役割・値の欠落が増えます。ボタンにdivやspanを用いる場合は、roleとキーボードイベント、押下状態のaria-pressedなど、必要な属性を正しく付与します。ReactやVueのルーティングでは、画面遷移時にメイン見出しへフォーカスを移し、ドキュメントタイトルを更新してコンテキストを提示します。ライブリージョンは情報の重要度に応じてpoliteとassertiveを使い分け、過剰な読み上げを避けます。

<!-- Code 11: カスタムボタンの意味づけ -->
<div role="button" tabindex="0" aria-pressed="false" aria-label="お気に入りに追加"></div>
// Code 12: Reactでの遷移時フォーカスとタイトル
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';

export function MainHeading({ children }) {
  const ref = useRef(null);
  const loc = useLocation();
  useEffect(() => {
    document.title = `${children} | Example`;
    ref.current?.focus();
  }, [loc]);
  return <h1 tabIndex="-1" ref={ref}>{children}</h1>;
}
// Code 13: ライブリージョンの最小実装
const region = document.getElementById('live');
function announce(msg, urgent = false) {
  region.setAttribute('aria-live', urgent ? 'assertive' : 'polite');
  region.textContent = '';
  setTimeout(() => { region.textContent = msg; }, 50);
}
<!-- 補助的に配置 -->
<div id="live" aria-live="polite" aria-atomic="true" class="sr-only"></div>

デザインシステムへの組み込みは、ガイドラインの静的文書化では不十分です。各コンポーネントのストーリーにアクセシビリティの使用例とアンチパターンを併記し、jest-axe等の自動検査を組み込み、Pull Requestでの逸脱を早期に検出します。セマンティクスが崩れやすいコンポーネント、たとえばトグルボタン、タブ、アコーディオン、メニュー、モーダル、トーストは、相互運用性の高いARIAパターンに寄せて再設計するのが安全です。Storybookのアクセシビリティアドオンで視覚回帰と併せて差分を確認し、axeの違反ゼロを出荷条件にする運用は有効です。記事内のパターンは詳細とも整合します。

試験・公開・運用のループを回す

試験は、人手による探索的テストと自動検査のハイブリッドが現実的です。探索は画面読み上げとキーボードで主要導線を一筆書きに辿り、見出し、ランドマーク、フォーム、エラー、ダイアログ、メディアの順に負荷をかけていきます。自動検査はLighthouse CIとaxe-core、pa11yをCIに統合し、テンプレートごとのしきい値で失敗させます。結果はスクリーンショットとともに保持し、回帰の起点とします。社外への試験結果公開ページには、対象範囲、達成等級、試験日、対象ブラウザ・支援技術、達成状況、例外、改善の予定を記載します。

見直しポイントの要約と投資対効果の見積もり

JIS AA対応を初めて進めるチームでは、骨格、操作、知覚、堅牢性の順にテコ入れすると効果が出やすいと感じます。骨格では唯一のh1、順序正しい見出し、ランドマーク、スキップリンクを確立します。操作ではキーボードで全機能に到達でき、フォーカスが見えること、フォームのラベルとエラーの関連付けが済んでいることを確認します。知覚ではコントラスト、字幕、動きの抑制、リフロー要件の順守を点検します。堅牢性では、名前・役割・値の欠落を取り除き、ARIAは必要最小限に留めます。これらをテンプレート横断で押さえるだけで、自動検査での違反件数が大きく減ることが期待でき、ユーザーからの問い合わせ削減につながる可能性があります。

費用対効果は、移行初期に発生するデザイン修正と実装の再配線をどう最小化するかにかかっています。デザイントークンでコントラストを担保し、コンポーネントの雛形にセマンティクスとフォーカス管理を組み込めば、機能追加時の増分コストは限定的です。KPIは、Lighthouse Accessibility 90以上の維持、Critical/Serious違反ゼロの継続、モバイルでのキーボード操作の阻害ゼロ、字幕カバレッジ100%といった目標を中期に置くと、チームの優先度付けとレビューが回りやすくなります。適合主張の公開は、調達・パートナー審査での説得力を高め、営業や海外展開の摩擦を減らす観点でも有効です。

まとめ:チェックリストをコードとCIに落とし込む

アクセシビリティは「後から付ける品質」ではなく、設計・実装・検証のサイクルに埋め込む品質です。JIS X 8341-3とWCAG 2.1/2.2の要件を、見出し構造、代替テキスト、キーボード操作、フォーカス、コントラスト、メディア対応、SPAのフォーカス管理という具体的なコードに変換し、CIで継続検証する流れができれば、リグレッションの恐怖は確実に減ります。あなたのプロダクトで今日見直せるのはどこでしょうか。スキップリンクを可視化し、フォームのエラー関連付けを点検し、主要導線をキーボードで通し、字幕のない動画を洗い出すだけでも、体験は着実に良くなります。次のスプリントで、axeの違反ゼロとLighthouse 90+を出荷条件に加えてみてください。小さな合格の積み重ねが、組織全体の動きを変えます。

参考文献

  1. World Health Organization. Disability - Overview. https://www.who.int/health-topics/disability#:~:text=Overview
  2. WebAIM. The WebAIM Million. https://webaim.org/projects/million/?ref=jina-ai-gmbh.ghost.io#:~:text=95.9,WCAG%202%20A%2FAA%20conformance%20was
  3. ウェブアクセシビリティ基盤委員会(WAIC). JIS X 8341-3:2016 解説(理解). https://waic.jp/docs/jis2016/understanding/201604/#:~:text=%E3%80%8EJIS%20X%208341,3%3A2016%E3%80%8F%E3%81%AE%E6%9C%80%E3%82%82%E5%A4%A7%E3%81%8D%E3%81%AA%E9%81%95%E3%81%84%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82
  4. W3C WAI. Understanding Success Criterion 2.4.1: Bypass Blocks. https://www.w3.org/WAI/WCAG21/Understanding/bypass-blocks.html#:~:text=Success%20Criterion%20
  5. W3C WAI. Understanding Success Criterion 1.1.1: Non-text Content. https://www.w3.org/WAI/WCAG21/Understanding/non-text-content#:~:text=Goal%20Non,hear%20content%20can%20understand%20it
  6. W3C WAI. Understanding Success Criterion 3.3.1: Error Identification. https://www.w3.org/WAI/WCAG21/Understanding/error-identification#:~:text=Goal%20Users%20know%20an%20error,reduced%20sight%20and%20cognitive%20disabilities
  7. W3C WAI. Understanding Success Criterion 2.4.7: Focus Visible (WCAG 2.2). https://www.w3.org/WAI/WCAG22/Understanding/focus-visible#:~:text=Goal%20Users%20know%20which%20element,users%20cannot%20operate%20the%20page
  8. W3C WAI. Understanding Success Criterion 1.4.3: Contrast (Minimum). https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum#:~:text=The%20visual%20presentation%20of%20text,5%3A1%2C%20except%20for%20the%20following
  9. W3C WAI. Understanding Success Criterion 1.4.10: Reflow. https://www.w3.org/WAI/WCAG21/Understanding/reflow#:~:text=,equivalent%20to%20256%20CSS%20pixels
  10. W3C WAI. Understanding Success Criterion 2.5.7: Dragging Movements (WCAG 2.2). https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements#:~:text=Goal%20Don%E2%80%99t%20rely%20on%20dragging,a%20mouse%20to%20drag%20items
  11. W3C WAI. Understanding Focus Appearance and Focus Not Obscured (WCAG 2.2). https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance
  12. W3C WAI. Understanding Success Criterion 2.5.8: Target Size (Minimum) (WCAG 2.2). https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum
  13. W3C WAI. Understanding Success Criterion 3.3.7: Redundant Entry (WCAG 2.2). https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry
  14. W3C WAI. Understanding Success Criterion 3.3.8: Accessible Authentication (Minimum) (WCAG 2.2). https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum
  15. W3C WAI. Understanding Success Criterion 3.2.6: Consistent Help (WCAG 2.2). https://www.w3.org/WAI/WCAG22/Understanding/consistent-help