コンテンツにスキップ

フォーカスの可視化

このガイドラインが達成されないとどうなるか

Section titled “このガイドラインが達成されないとどうなるか”

結果的に、使いやすさが大きく損なわれ、「使えるのに使えない」状態に陥ります。

具体例:業務での困りごと

Aさんは大量のデータをシステムに入力する業務を担当しており、作業をスピードアップするためキーボード操作で画面を移動しています。 ところが、フォーカスが見えない画面では、どのボタンが選択されているか分かりません。 その結果、登録ボタンを押すつもりがキャンセルを押してしまうなどのミスが頻発し、業務効率が下がりました。

以下のデモでTabキーを押してフォーカスの違いを体験してください。

悪い例: フォーカスが見えない

/* アクセシビリティ上問題があるスタイル */
.button:focus {
  outline: none; /* フォーカスが見えなくなる! */
}

.link:focus {
  outline: none; /* これも見えない */
}

/* 装飾用スタイル */
.button {
  padding: 12px 24px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.link {
  color: #007bff;
  text-decoration: none;
  padding: 8px;
}

良い例: フォーカスがしっかり見える

/* アクセシビリティを満たすスタイル */
.button:focus-visible {
  outline: 2px solid #005fcc; /* しっかり見える */
  outline-offset: 2px;
}

.link:focus-visible {
  outline: 2px solid #005fcc; /* これも見える */
  outline-offset: 2px;
}

/* 装飾用スタイル */
.button {
  padding: 12px 24px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.link {
  color: #007bff;
  text-decoration: none;
  padding: 8px;
  border-radius: 4px;
}

最低限、すぐに取り組めること

Section titled “最低限、すぐに取り組めること”
  • 機能要件に「フォーカス可能要素で、キーボード操作時に視認可能なフォーカススタイルを表示する」を明記する
  • コンポーネントにフォーカス状態を定義する(FigmaではVariantsで管理する)
  • 推奨スタイルか確認する
    • 背景や非フォーカス状態とのコントラスト比が3:1以上
    • フォーカスリングで表現する場合、太さが2px以上
  • :focus-visible 擬似クラスでフォーカスリングを当てる
  • UIライブラリのフォーカス管理機能を活用する
  • Tabキーで画面全体を巡回し、フォーカス表示を確認する
  • コントラスト比が3:1以上であることを確認する
  • フォーカスが見えづらい箇所のフィードバックを収集する
  • 気づいた時点で小まめに修正し継続改善する

デザインが崩れると言われたとき(デザインに合わないと言われたとき)

Section titled “デザインが崩れると言われたとき(デザインに合わないと言われたとき)”

1. outline-offsetを使用して要素と重ならないようにする

Section titled “1. outline-offsetを使用して要素と重ならないようにする”

要素と重ならない位置でフォーカススタイルを表示できます。

/* outline-offsetで要素から離れた位置に表示 */
.button:focus-visible {
  outline: 2px solid #ff6b35;
  outline-offset: 4px; /* 要素に重ならずに表示 */
}

.link:focus-visible {
  outline: 2px solid #ff6b35;
  outline-offset: 2px; /* リンクも同様 */
}

/* 装飾用スタイル */
.button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 12px 24px;
  margin: 8px;
  border-radius: 4px;
  cursor: pointer;
}

.link {
  color: #007bff;
  text-decoration: none;
  padding: 8px;
  border-radius: 4px;
  margin: 8px;
  display: inline-block;
}

box-shadowを使用するとより柔軟なデザインを実現できます。

/* box-shadowを活用した柔軟なデザイン例 */
.button:focus-visible {
outline: 2px solid transparent; /* ハイコントラストモードで表示 */
box-shadow:
0 0 0 3px rgba(59, 130, 246, 0.6), /* フォーカスリング */
0 0 8px 2px rgba(59, 130, 246, 0.3), /* ぼかしフォーカスリング */
0 4px 12px rgba(59, 130, 246, 0.3), /* ドロップシャドウ */
inset 0 1px 0 rgba(255, 255, 255, 0.2); /* 内側のハイライト */
}

.link:focus-visible {
outline: 2px solid transparent;
box-shadow:
0 0 0 2px rgba(30, 64, 175, 0.6), /* フォーカスリング */
0 0 4px 1px rgba(30, 64, 175, 0.3); /* ぼかしフォーカスリング */
background-color: rgba(30, 64, 175, 0.08);
border-radius: 3px;
}

/* 装飾用スタイル */
.button {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
color: white;
border: none;
padding: 14px 28px;
margin: 8px;
border-radius: 12px;
cursor: pointer;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease;
}

.link {
color: #1e40af;
text-decoration: underline;
padding: 4px 2px;
margin: 8px;
display: inline;
transition: all 0.2s ease;
}

3. 背景色やアイコンを変化させる

Section titled “3. 背景色やアイコンを変化させる”

フォーカスの順序が直感的でない

Section titled “フォーカスの順序が直感的でない”
  1. HTML構造を見直す(最優先)
  2. tabindexを使用する
    • tabindex="-1":JavaScriptからのみフォーカス可能
    • tabindex="0":カスタム要素などを通常のタブ順序に含める
    • tabindex="1" 以上:タブ順序を強制的に変更する(使わない)
  3. CSSで視覚的な順序だけを変更する
CSS Flexboxで視覚順序を変更
.container {
display: flex;
flex-direction: column;
}
.visual-first {
order: -1;
}

モーダルなポップアップやダイアログでフォーカスが外に逃げる

Section titled “モーダルなポップアップやダイアログでフォーカスが外に逃げる”

モーダル表示時にはフォーカスをモーダル内で循環させます。

多くのUIライブラリはこの機能を提供しているため、利用を検討してください。

自前で実装をする場合は以下のライブラリを検討してください。

UIライブラリのフォーカスインジケータのスタイリングが不十分

Section titled “UIライブラリのフォーカスインジケータのスタイリングが不十分”

Material-UIやChakra UIなどでは、テーマやコンポーネント単位でfocus-visibleスタイルの上書きが可能です。

まとめて適用することで、個別対応の手間を減らせます。

関連項目(別ガイドライン対象)

Section titled “関連項目(別ガイドライン対象)”
  • Tabキーだけで機能にアクセスできる
  • フォーカスされた要素が他の要素で隠されていない
擬似クラス特徴使用場面
:focusマウスでもキーボードでもフォーカス時に有効。古いブラウザでも使える後方互換性が必要な場合
:focus-visible基本的には推奨。キーボード操作時など、「フォーカスを表示するべき場合のみ」に有効モダンブラウザでのフォーカス表示
:focus-within子要素にフォーカスがある場合も親要素に適用されるフォーム全体やカードコンポーネントのハイライト

box-shadowを使用する場合の注意点

Section titled “box-shadowを使用する場合の注意点”

box-shadowを使用することで柔軟なデザインを実装できます。ただし、Windowsのハイコントラストモードでは表示されないため、outline: 2px solid transparentと併用します。ハイコントラストモードではtransparentが適切な色に変換されます。

box-shadowとoutline併用の推奨実装
:focus-visible {
outline: 2px solid transparent;
box-shadow: 0 0 0 3px red;
}
アニメーション付きフォーカスリング
:focus-visible {
outline-offset: 0;
transition: outline-offset 0.25s ease-out;
}
:focus-visible {
outline-offset: 2px;
}
/* アニメーションを望まないユーザーにはアニメーションを無効化する */
@media (prefers-reduced-motion: reduce) {
:focus-visible {
transition: none;
}
}
CSS変数を利用したダークモード対応の例
:root {
--focus-ring: #005fcc;
}
@media (prefers-color-scheme: dark) {
:root {
--focus-ring: #4d9fff;
}
}
:focus-visible {
outline: 2px solid var(--focus-ring);
}

フォーカストラップの基本的な考え方

Section titled “フォーカストラップの基本的な考え方”
  1. 最初の要素と最後の要素のフォーカス要素を取得
  2. 最後の要素でTab → 最初の要素へ戻す
  3. 最初の要素でShift+Tab → 最後の要素へ戻す
  4. モーダル表示時に最初の要素へフォーカス