著者: 著者: 8091.info タグ:
  • キーボードナビゲーション
  • フォーカス管理
  • UX
キーボードのTabキーにフォーカスが当たっている写真

キーボードナビゲーションの重要性

マウスやタッチパッドを使用できないユーザーにとって、キーボードは主要な操作手段です。これには以下のようなユーザーが含まれます:

  • 視覚障害者(スクリーンリーダー使用者)
  • 運動機能障害者
  • 一時的にマウスが使用できない状況のユーザー
  • キーボード操作を好むパワーユーザー

基本的なキーボード操作

主要なキーとその役割

  • Tab: 次の要素にフォーカス移動
  • Shift + Tab: 前の要素にフォーカス移動
  • Enter: リンクやボタンの実行
  • Space: ボタンの実行、チェックボックスの切り替え
  • 矢印キー: メニューやタブ内での移動
  • Esc: モーダルやメニューの閉じる

フォーカス可能な要素

以下の要素は自然にフォーカスを受け取ることができます:

<!-- 自然にフォーカス可能 -->
<a href="/page">リンク</a>
<button>ボタン</button>
<input type="text" placeholder="テキスト入力" />
<select>
  <option>選択肢</option>
</select>
<textarea>テキストエリア</textarea>

実装のベストプラクティス

1. 論理的なTab順序

Tab順序は視覚的な配置と一致させることが重要です:

<!-- 良い例: 自然な順序 -->
<form>
  <input type="text" placeholder="名前">
  <input type="email" placeholder="メールアドレス">
  <button type="submit">送信</button>
</form>

<!-- 避けるべき例: tabindexで無理やり順序を変更 -->
<form>
  <input type="text" tabindex="3">
  <input type="email" tabindex="1">
  <button type="submit" tabindex="2">
</form>

2. 明確なフォーカスインジケーター

ユーザーが現在どの要素にフォーカスがあるかを明確に示します:

/* デフォルトのoutlineを削除しない */
button:focus {
  outline: 2px solid #007acc;
  outline-offset: 2px;
}

/* より分かりやすいカスタムフォーカス */
.custom-button:focus {
  box-shadow: 0 0 0 3px rgba(0, 122, 204, 0.5);
  border-color: #007acc;
}

3. スキップリンクの実装

長いナビゲーションをスキップできるリンクを提供:

<a href="#main-content" class="skip-link"> メインコンテンツへスキップ </a>

<nav><!-- 長いナビゲーション --></nav>

<main id="main-content">
  <!-- メインコンテンツ -->
</main>
.skip-link {
  position: absolute;
  top: -40px;
  left: 6px;
  z-index: 1000;
  background: #000;
  padding: 8px;
  color: #fff;
  text-decoration: none;
}

.skip-link:focus {
  top: 6px;
}

複雑なUIパターンの対応

ドロップダウンメニュー

// キーボード操作に対応したドロップダウン
const dropdown = {
  handleKeyDown(event) {
    switch (event.key) {
      case 'ArrowDown':
        this.focusNext()
        break
      case 'ArrowUp':
        this.focusPrevious()
        break
      case 'Escape':
        this.close()
        break
      case 'Enter':
      case ' ':
        this.selectItem()
        break
    }
  },
}

モーダルダイアログ

// フォーカストラップの実装
function trapFocus(element) {
  const focusableElements = element.querySelectorAll(
    'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
  )

  const firstElement = focusableElements[0]
  const lastElement = focusableElements[focusableElements.length - 1]

  element.addEventListener('keydown', (e) => {
    if (e.key === 'Tab') {
      if (e.shiftKey && document.activeElement === firstElement) {
        lastElement.focus()
        e.preventDefault()
      } else if (!e.shiftKey && document.activeElement === lastElement) {
        firstElement.focus()
        e.preventDefault()
      }
    }
  })
}

テストと検証

手動テスト

  1. マウスを使わずにTabキーだけでサイト全体を操作
  2. すべてのインタラクティブ要素にアクセス可能か確認
  3. フォーカスが見える状態になっているか確認
  4. 論理的な順序でフォーカスが移動するか確認

自動テスト

// axe-coreを使用した自動テスト
import { axe } from 'jest-axe'

test('should not have accessibility violations', async () => {
  const results = await axe(document.body)
  expect(results).toHaveNoViolations()
})

まとめ

キーボードナビゲーションの実装は、アクセシビリティの基本であり、すべてのユーザーにとって使いやすいサイト作りの第一歩です。小さな配慮の積み重ねが、大きな違いを生むことを忘れずに、継続的に改善していきましょう。