トグルスイッチデザインシステム は何をしますか?
目的
トグルスイッチデザインシステムは、Webインターフェース全体でバイナリ状態コントロールを設計、配置、実装するための標準化フレームワークを提供します。トグルスイッチは物理的なオン/オフスイッチを表し、手動でフォームを送信(「保存」ボタンをクリックするなど)することなく、状態変更、設定、機能ステータスを即座にトリガーまたは切り替えます。
専用のスイッチデザインシステムがないと、インターフェースは次のような問題を頻繁に引き起こします:チェックボックスの代わりにトグルスイッチを誤用する、無効状態や非アクティブ状態でWCAGのコントラスト要件を満たさない、明確な状態ラベルが欠如している、モバイル画面には小さすぎるタッチターゲットを作成する、または即時の視覚的フィードバックなしに予期しないレイアウトシフトやバックグラウンド副作用を引き起こす。
このシステムは、スイッチの幾何学的寸法、トラックとサムの比率、ラベル配置、状態の色マッピング、キーボードアクセシビリティ(role="switch")、タッチヒットエリア拡張、レスポンシブリストレイアウト、および非同期ペンディング/ローディング状態に関するルールを確立します。
ユースケース
- アプリケーション設定と環境設定: システム環境設定の即時切り替え(例:「プッシュ通知」「ダークテーマ」「下書きの自動保存」「二要素認証」)。
- サブスクリプションと請求期間の選択: 請求サイクルを月次と年次で切り替える料金カード層の切り替え(インラインバッジ付き)。
- データテーブル行コントロール: データテーブル行内で直接、個々のユーザーアクセス、API統合、ウェブフック、自動化ルールを有効または無効にする。
- 機能フラグとシステムモードのトグル: 開発者ダッシュボードでの動作状態の切り替え(例:「メンテナンスモード」「デバッグロギング」「ベータ機能」)。
- プライバシーとCookie同意パネル: スライドアウトメニューやモーダルダイアログ内で詳細なトラッキング許可を管理する(例:「アナリティクスCookie」「マーケティングCookie」)。
使用すべきでない場合
- 複数選択肢の選択: 3つ以上の排他的選択肢を選択する場合は、
segmented-control-systemまたはcustom-select-and-combobox-systemを使用します。 - 明示的な承認が必要なフォーム送信: 標準の複数フィールドフォーム内で「送信」ボタンのクリックが必要な同意条項(例:「利用規約に同意します」)の場合は、標準のチェックボックス(
form-design-system)を使用します。 - 即時効果がないバイナリ選択: コントロールを切り替えても、二次的な「適用」または「変更を保存」ボタンが押されるまで効果が発現しない場合は、スイッチの代わりにチェックボックスを使用します。
- テーブル内の一括選択: バッチ操作(例:「選択した項目を削除」)のために複数の項目を選択する場合は、チェックボックス(
data-table-ui-system)を使用します。
入力
- 状態定義: バイナリ状態パラメータ(Off/Unchecked/
falsevs On/Checked/true)。 - コンテキストと実行モード: 即時クライアント側状態変更(例:ダークテーマスイッチ) vs 非同期サーバー副作用(例:APIウェブフックの有効化/無効化)。
- ラベル構造: インラインラベルテキスト、補足説明/ヘルプテキスト、ステータスバッジの要件。
- レイアウトコンテキスト: スタンドアロン設定カード、密集したテーブル行、複数項目の環境設定グループ、ヒーロー価格トグル。
- テーマとトークンパレット: 表面色、アクティブトラック色、非アクティブトラック色、サム色、フォーカスリングオフセットトークン。
出力
- スイッチの幾何学的寸法とトークン仕様: トラック幅、高さ、サム直径、角丸、トランジションタイミングの空間的寸法(
width: 44px、height: 24px、thumb: 20px)。 - 状態とコントラストの設計図: デフォルト(Off)、アクティブ(On)、ホバー、フォーカス可視、無効、ペンディング状態全体で、トラックとサムにWCAG 3:1のグラフィカルオブジェクトコントラストの最小値を保証するパレットトークン。
- 構造レイアウトとタイポグラフィ仕様: スイッチ要素、プライマリラベル(
h4/span)、説明テキスト、オプションのステータスインジケータ(ON/OFF)間の間隔関係。 - アクセシビリティとARIAマッピング: セマンティックHTML
<button role="switch" aria-checked="true|false">構造と、スクリーンリーダーラベル関連付け(aria-labelledby/aria-describedby)。 - 非同期処理プロトコル: バックグラウンドネットワーク検証のための視覚的ローディング状態仕様(スピナーサムまたはトラック不透明度の低下)。
ワークフロー
1. コントロールのセマンティクスを決定する(スイッチ vs チェックボックス)
ビジュアルデザインの前に、インタラクションの意図が物理的なスイッチのメンタルモデルと一致していることを確認します:
- 即時効果: スイッチを切り替えると、即座に効果が発現する(または即座にバックグラウンドリクエストがトリガーされる)。
- スタンドアロンアクション: 明示的な「保存」や「送信」確認ボタンを必要とせずに独立して動作する。
- オン/オフ状態のメタファー: 複数フィールドのアンケートで選択を行うのではなく、機能やステータスをオンまたはオフにすることを表す。
2. 空間的幾何学とタッチマージンを確立する
デスクトップでの視覚的な調和を維持しながら、モバイルタッチガイドラインに沿った比率でスイッチコンポーネントを設計します:
[ 非アクティブ/オフ トラック ] [ アクティブ/オン トラック ]
+--------------------------+ +-------------------------+
| (サム) | -----> | (サム) |
| 20px | | 20px |
+--------------------------+ +-------------------------+
<-------- 44px -----------> <-------- 44px ----------->
24px 高さ 24px 高さ
- 標準スイッチスケール:
- トラック幅:
44px(または2.75rem) - トラック高さ:
24px(または1.5rem) - トラックの角丸:
999px(完全なピル形状) - サム直径:
20px(全側面に2pxの内側トラックインセットを残す) - サムの角丸:
50%(円形)
- トラック幅:
- コンパクト/高密度スイッチスケール(テーブル行):
- トラック幅:
36px - トラック高さ:
20px - サム直径:
16px(2pxのインセットあり)
- トラック幅:
- タッチターゲットエンクロージャ:
- インタラクティブなヒットゾーンは、疑似要素(
::before/::after)またはパディングを使用して、モバイルデバイスで少なくとも 44x44px に拡張する必要があります。これにより、タッチスクリーンでの誤クリックを防ぎます。
- インタラクティブなヒットゾーンは、疑似要素(
3. 状態カラートークンとコントラストメトリクスを定義する
WCAG 2.1 / 2.2 AAの非テキストコントラスト要件(SC 1.4.11 - 最小3:1コントラスト)を満たすために、厳密なカラートークンペアに従います:
- 非アクティブ/オフ状態:
- トラック背景:ニュートラルグレー表面(
#E2E8F0/ ダークモード:#334155)。 - トラック境界線:1px 境界線(
#CBD5E1/ ダークモード:#475569)。明るい背景表面に対する3:1のコントラストを保証します。 - サム色:無地の白または明るい表面(
#FFFFFF/ ダークモード:#F8FAFC)。 - サム内のオプションアイコン:二重の視覚的フィードバックのための月/太陽または×/チェックアイコン(
12px)。
- トラック背景:ニュートラルグレー表面(
- アクティブ/オン状態:
- トラック背景:高コントラストのブランドまたはシステムアクション色(
#2563EBプライマリブルーまたは#16A34Aサクセスグリーン)。背景ページ表面に対するコントラスト比は3:1を超える必要があります。 - トラック境界線:透明またはアクティブ境界線に一致。
- サム色:無地の白(
#FFFFFF)。スムーズなCSSトランジション(transform: translateX(20px)、200ms cubic-bezier(0.4, 0, 0.2, 1))が必要。
- トラック背景:高コントラストのブランドまたはシステムアクション色(
- ホバー&フォーカス状態:
- ホバー:微妙なトラックの明るさシフト(+5%または-5%)またはサムシャドウの拡大(
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.15))。 - フォーカス可視:明確な2pxオフセットフォーカスリング(
outline: 2px solid #2563EB; outline-offset: 2px)。
- ホバー:微妙なトラックの明るさシフト(+5%または-5%)またはサムシャドウの拡大(
- 無効状態:
- トラックとサムの不透明度:
0.5または0.4に低下し、cursor: not-allowedを設定。
- トラックとサムの不透明度:
4. ラベル配置と説明の階層をレイアウトする
スイッチには常に明確なテキストラベルを添える必要があります。アクセシブルなラベルや可視的なコンテキストなしに、単独のスイッチを表示してはいけません。
- 水平行レイアウト(デフォルトの設定カード):
- テキストブロックを左側(タイトル+説明)に配置し、スイッチを右端に配置します。
- スイッチトラックの垂直中心を、タイトルテキストの最初の行に合わせます(複数行の説明全体の中央ではありません)。
- タイトルテキストとスイッチ要素の間に最低
16pxのギャップを維持します。
- フォームインラインレイアウト:
- スイッチを左側、ラベルテキストを右側に配置します(
gap: 12px)。スイッチが密集したフォームフィールド内に統合される場合に推奨されます。
- スイッチを左側、ラベルテキストを右側に配置します(
- 料金階層トグルレイアウト:
- スイッチを2つの明示的なラベルオプション(例:「月次」— [スイッチ] —「年次(20%お得)」)の間に水平方向に中央揃えします。いずれかのテキストラベルまたはスイッチをクリックすると、アクティブ状態が切り替わります。
5. 非同期副作用とローディング状態を処理する
スイッチが非同期API呼び出し(例:クラウドリソース設定の変更や統合の有効化)をトリガーする場合:
- 楽観的ビジュアル状態: サムをターゲット位置に即座にスライドさせます(
aria-checked="true")。 - ペンディングフィードバック: ネットワークレイテンシ中に、サム内に微妙なスピナーオーバーレイをレンダリングするか、トラックの不透明度をわずかに下げます。
- エラーリカバリ: サーバーがエラーを返した場合、インラインのトースト/アラートメッセージを表示し、サムを以前の状態にスムーズにアニメーションで戻し、
aria-checked="false"に設定します。
6. WCAG AAアクセシビリティパターンを実装する
すべてのブラウザエンジンでネイティブのキーボードナビゲーションとスクリーンリーダーサポートを確保します:
- セマンティックHTMLマークアップ:
<button type="button" role="switch" aria-checked="true" id="push-notifications-switch" aria-labelledby="push-notifications-label" aria-describedby="push-notifications-desc" class="toggle-switch"> <span class="toggle-switch__track"> <span class="toggle-switch__thumb"></span> </span> </button> - キーボードインタラクション:
Tabキーナビゲーションでフォーカス可能。SpaceキーまたはEnterキーを押すと、aria-checked状態(true<->false)が切り替わり、関連するハンドラーがトリガーされます。
- スクリーンリーダーのアナウンス:
- スクリーンリーダーは、「プッシュ通知、スイッチ、オン」または「プッシュ通知、スイッチ、オフ」と明示的にアナウンスします。
- スイッチのネイティブARIA状態と重複する場合は、ラベル内に「オン/オフ」のようなテキストを記述しないでください。
決定ルール
スイッチ vs チェックボックス vs セグメントコントロールの選択マトリックス
| シナリオ / 要件 | 推奨コントロール | 理由 |
|---|---|---|
| 即時効果のある単一バイナリ選択(例:ダークテーマ) | トグルスイッチ | 即時実行モデルが物理スイッチと一致する。 |
| 送信されるフォーム内の単一バイナリ選択(例:利用規約に同意) | チェックボックス | 「送信」ボタンがクリックされるまで変更は有効にならない。 |
| リストからの複数項目選択(例:5件のメールを選択) | チェックボックス | 標準のバッチ選択動作。 |
| 2つの異なるモード間の選択(例:グリッドビュー vs リストビュー) | セグメントコントロール | 両方の状態ラベルが並んで表示されたままになる。 |
| モバイルリストビュー内でオプションをオン/オフに設定する | トグルスイッチ | 明確なサムターゲットと明示的な状態フィードバック。 |
ラベル配置マトリックス
| レイアウトコンテキスト | スイッチの位置 | ラベルの位置 | 空間的動作 |
|---|---|---|---|
| 設定環境設定リスト | 右揃え | 左揃え | 行コンテナ全体に justify-content: space-between。 |
| インラインフォームフィールド | 左揃え | 右揃え | display: inline-flex; align-items: center; gap: 12px。 |
| ヒーロー価格トグル | 中央アンカー | 左右両側 | 「月次」と「年次」のテキストオプションで挟まれる。 |
制約事項
- アクセシビリティ(WCAG 2.1 / 2.2 AA):
- オン状態とオフ状態の両方において、トラックの境界線/背景およびサムとページ背景の間で、最低3:1の非テキストコントラスト比。
- 関連するすべてのラベルと説明ヘルパーテキストに対して、最低4.5:1のテキストコントラスト比。
- フォーカスリングは、周囲の背景に対して少なくとも3:1のコントラストを提供し、少なくとも2pxの太さが必要。
- タッチターゲット:
- タッチデバイスでのインタラクティブタッチ領域は、少なくとも 44x44px である必要があります(WCAG 2.5.5 / 2.5.8)。
- 色の独立性:
- 色は状態の唯一の指標であってはなりません。サムの物理的な空間位置(左=オフ、右=オン)とセマンティックな
aria-checked値が、色とは独立して状態を伝える必要があります。
- 色は状態の唯一の指標であってはなりません。サムの物理的な空間位置(左=オフ、右=オン)とセマンティックな
よくある障害パターン
- 送信されるフォームでのスイッチの誤用: 別の「保存」ボタンをクリックするまで変更が有効にならないフォーム内でスイッチを使用し、即時適用を期待するユーザーを混乱させる。
- 不十分なトラックコントラスト: 境界線なしで白い背景に対して明るいグレーのトラック(
#F1F5F9)を使用し、スイッチをロービジョンユーザーに見えなくする。 - 色のみの状態伝達: サムスライダーの位置を移動したりARIA属性を更新したりせずに、赤と緑のトラック色のみに依存する。
- 微小なタッチターゲット: ヒットゾーンを36x20pxの視覚的なトラックに制限し、モバイルビューポートでのフラストレーションとタップミスを引き起こす。
- アクセシブルなラベルの欠落:
aria-labelまたはaria-labelledby参照なしに、スタンドアロンのアイコンスイッチをレンダリングする。 - 複数行テキストの重なり: 長い4行の説明段落に対してスイッチを垂直方向に中央揃えし、メインタイトルとの視覚的な配置を崩す。
検証基準
- スイッチはセマンティックHTML
<button role="switch" aria-checked="true|false">構造を使用している。 - トラックとサムは、ON状態とOFF状態の両方で、背景に対して最低3:1のコントラスト比を満たしている。
- キーボードナビゲーション(
Tab、Space、Enter)でスイッチの状態がスムーズに切り替わり、aria-checkedが更新される。 - タッチヒットエリアは、非表示のパディングまたは疑似要素を使用して少なくとも44x44pxに拡張されている。
- スイッチには、
aria-labelledbyを介して関連付けられた、視覚的で高コントラストなラベルテキストがペアになっている。 - スイッチの位置は、
prefers-reduced-motionに対応しながら、150ms~250msでスムーズにトランジションする(transform: translateX())。 - レスポンシブ設定リストは、狭いモバイル画面でテキストが重なることなく、適切な間隔(
gap: 16px)を維持している。