SSB - ボタンに関する統一基準

SSB - ボタンに関する統一基準
基準

31

9 分。

定義

SSB基準は、ボタンの意味、アクセシビリティ、および動作ロジックに関する要件を規定しています。

構造とセマンティクス

ボタンの用途とtype

  • 操作にはネイティブの<button>要素を使用する。イベントハンドラーを設定した<div>や<span>は、ボタンのセマンティクスやキーボード操作を自動では備えない。
  • すべてのボタンにtype属性を明示する。値は配置場所だけでなく、ボタンの目的に合わせる。
    • type="submit" — 関連付けられたフォームを送信する。
    • type="button" — フォームの送信やリセットを行わずに、インターフェース上の操作を実行する。
    • type="reset" — フォームの各コントロールを初期値に戻す。
  • typeを省略すると、フォームが送信される場合がある。既定の動作はコンテキストとフォームとの関連付けによって異なる。form属性を使うと、<form>の外にあるボタンもフォームに関連付けられる。
  • type="reset"は、初期値に戻すことが意図された動作である場合に限って使用する。リセットは必ずしも入力欄を空にするものではなく、各コントロールの既定値に戻す。

ボタンのグループ化

  • 関連するボタンはセマンティクスを付けてグループ化する。通常のグループにはアクセシブルな名前を持つrole="group"を使用する。関連するフォームコントロールには<fieldset>と<legend>を使用する。
  • role="toolbar"は実際のツールバーに使用し、一般的なグループの代わりにはしない。ツールバーでは、矢印キーで各コントロール間を移動できるようにし、それに応じてフォーカスを管理する。
  • ラベルが変わらないトグルボタンでは、aria-pressed="true"またはaria-pressed="false"で状態を伝える。たとえばラベルが「再生」から「一時停止」に変わる場合、通常はaria-pressedを追加しない。

アクセシビリティ

アクセシブルな名前とキーボード操作

  • 通常、ボタン内のテキストがアクセシブルな名前になる。アイコンのみのボタンには、aria-labelまたはaria-labelledbyで目的が分かる名前を付ける。
  • すでに分かりやすいテキストラベルを補足するアイコンは、たとえばaria-hidden="true"を指定して装飾として扱う。必要がない限り、aria-labelで同じ名前を重複させない。
  • ネイティブボタンはEnterキーとSpaceキーで実行できる。独自のイベントハンドラーで標準のキーボード操作を妨げたり、同じ処理を二重に実行したりしない。
  • 通常の操作後はフォーカスをボタンに維持する。ダイアログを開く、またはコンテキストを変更する操作では、遷移先の要件に沿ってフォーカスを移動する。

フォーカスと状態

  • フォーカスインジケーターは、同等に視認できる表示に置き換えずに削除しない。キーボードフォーカスのスタイルには:focus-visibleを使用し、利用するすべての背景上でコントラストと視認性を確認する。
  • :hover、:active、:focus-visible、:disabledの各状態は、該当する場合に見分けられるようにする。ホバーだけを操作の手掛かりにしない。タッチ操作ではホバーが利用できず、フォーカスや押下状態の代わりにもならない。
  • 操作できない状態にはネイティブのdisabled属性を使用する。aria-disabled="true"とは異なり、ボタンの実行を防ぎ、通常のフォーカス順から外す。
  • 操作できないボタンをフォーカス順に残す必要がある場合に限り、aria-disabled="true"を使用する。その場合、操作とイベントハンドラーを別途ブロックする。

非同期処理

  • 非同期処理を繰り返すと重複実行につながる場合は、再実行を防ぐ。処理中はボタンに一時的にdisabledを設定できる。
  • aria-busy="true"は対象要素が更新中であることを示すが、読み込み中のテキストを必ず通知するものではない。たとえばrole="status"を持つ要素で、状態を別途伝える。
  • 処理が完了したらaria-busyを解除し、ボタンを現在の状態に戻して、結果またはエラーを利用できるようにする。

インタラクションと視覚的なスタイル

カーソルとフィードバック

  • プロジェクトでカーソルを操作の手掛かりとして使う場合、有効なボタンにはcursor: pointer、無効なボタンにはcursor: not-allowedを指定する。カーソルは視覚的な補助にすぎず、ボタンのセマンティクスや状態の代わりにはならない。
  • 押下状態には、ボタンを1px下げるなど、控えめな視覚的フィードバックを加えてもよい。テキスト、フォーカス、その他の状態を見づらくしない。
  • prefers-reduced-motion: reduceが有効な場合、状態変化の理解に動きが必要でない限り、トランジションを短縮または無効にする。

ターゲットサイズ

  • タッチ端末で操作対象のサイズを確認する。WCAG 2.2 SC 2.5.8に適合するには、ターゲットを少なくとも24 × 24 CSS pxにするか、隣り合うターゲット間に十分な間隔を設けるなど、基準に定められた例外を満たす。
  • アイコンの見た目はタップ領域より小さくてもよいが、ボタンまたはそのコンテナーで十分なターゲットサイズを確保する。

テスト

  • すべてのボタンに適切なtypeが明示されている。フォーム内のボタンと、form属性でフォームに関連付けられたボタンの動作をそれぞれ確認する。
  • キーボード、ポインター、タッチで操作でき、通常の実行でフォーカスが予期せず移動しない。
  • スクリーンリーダーでボタンの名前と状態を理解できる。アイコンのみのボタンにもアクセシブルな名前がある。
  • :hover、:active、:focus-visible、disabled、読み込み中の状態を視覚的に区別でき、色やカーソルだけに依存していない。
  • 非同期処理中の連続実行、状態の通知、結果やエラーメッセージへのアクセスを確認する。
  • グループに適切なセマンティクスを使用する。role="toolbar"では、矢印キーによる移動、フォーカス管理、Tabキーの動作も確認する。
  • 適用可能な例外を考慮しつつ、ターゲットサイズがWCAG 2.2 SC 2.5.8に適合しているか確認する。

例

typeを明示したボタン:

<form action="/subscribe" method="post">
  <button type="submit">購読する</button>
  <button type="reset">初期値に戻す</button>
</form>

<button type="button">設定を開く</button>

アイコンのみのボタンとボタンのグループ:

<button type="button" aria-label="削除">
  <svg aria-hidden="true" viewBox="0 0 24 24">...</svg>
</button>

<div role="group" aria-label="書式設定">
  <button type="button" aria-pressed="false">太字</button>
  <button type="button" aria-pressed="false">斜体</button>
  <button type="button" aria-pressed="false">下線</button>
</div>

ボタンの状態とキーボードフォーカス:

button:enabled {
  cursor: pointer;
  transition: transform 120ms ease;
}

button:disabled {
  cursor: not-allowed;
}

button:hover:enabled {
  background-color: #e0e0e0;
}

button:active:enabled {
  background-color: #d0d0d0;
  transform: translateY(1px);
}

button:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  button {
    transition: none;
  }
}

フォーカスインジケーターと背景の色は、インターフェース全体のコントラストを考慮して選ぶ。:focus-visibleの表示はブラウザーの判定に従い、キーボード入力以外の状況でも現れることがある。

状態を別途通知する非同期処理:

<div aria-busy="true">
  <button type="submit" disabled>保存中...</button>
</div>

<p role="status">変更を保存しています</p>

aria-busyは更新中の領域を示し、role="status"はフォーカスを移動せずに状態変化を伝える。処理の完了後は領域のbusy状態を解除し、ボタンを更新して、ステータスで結果を伝える。

関連記事

  • Reactコンポーネントの構造

    各Reactコンポーネントがどのような外観であるべきか、私の考え

    421

    13 分。

  • SST - タブに関する統一規格

    SST規格は、タブのセマンティクス、アクセシビリティ、および動作ロジックに関する要件を規定しています

    62

    11 分。

  • SSF-U - フルスクリーン表示の統一規格

    SSF-U規格は、フルスクリーン表示のセマンティクス、アクセシビリティ、および動作ロジックに関する要件を規定しています

    248

    3 分。

  • SSA - アコーディオンの統一標準

    SSA規格は、アコーディオンのセマンティクス、アクセシビリティ、および動作ロジックに関する要件を定めています

    258

    4 分。

  • ウェブサイトにおける悪い慣行

    ウェブデザインにおける致命的なミスの分析。スライダー、自動再生、重いページがコンバージョン率やGoogleでの検索順位を低下させる理由

    232

    2 分。

  • SSP - ページネーションの統一規格

    SSP規格は、ページネーションのセマンティクス、アクセシビリティ、および動作ロジックに関する要件を規定しています

    240

    3 分。

  • すべての記事

ご連絡ください