「複数選択可」と「実行前の保留状態」を視覚的に約束する部品。Radio(排他選択)・Toggle Switch(即時反映)との使い分けが設計の核になる。
この記事を読むと、Checkbox / Radio / Toggle Switchの使い分け・Indeterminate実装・A11y要件の判断が自分でできるようになります。
1. UI例(Preview / Live)
実装で見る(GunjoUI)
この部品を、デザインシステム GUNJO の実装で確かめられます。
2. 定義(Definition)
ユーザーがリストの中から「0個以上」の複数の選択肢を個別にオン/オフできる入力部品。「保存ボタンを押すまで状態が確定しない」一時的な選択状態を表す。
3. 使い分け(When to use / When NOT to use)
3.1 When to use
- リストから複数(または0個)の項目を選ばせるとき
- 単一項目に「同意する」「記憶する」などのYes/Noを尋ねるとき
- フォームの「送信 / 保存」前の準備段階の入力であるとき
3.2 When NOT to use
- 複数の選択肢から必ず1つだけを選ばせる(Radio Buttonを使う)
- 押した瞬間に即座に設定が反映される(Toggle Switchを使う)
3.3 代替UI(Alternatives)
- 排他選択(1つだけ選ぶ) →
Radio Button - 即時反映の設定スイッチ →
Toggle Switch - 多数の選択肢から複数選ぶ →
Multi-Select/Combobox
4. 設計判断の核(Decision Principles)
「□は複数選べる、○は1つだけ」という普遍的な文法を守る。
判断の優先順位:① 複数選択可か排他選択か → ② 即時反映か保留か → ③ ラベルは肯定文か → ④ ヒット領域は十分か
- Checkbox = 複数選択可 + 保留型(保存ボタンで確定)
- Radio = 排他選択(必ず1つ)
- Toggle Switch = 即時反映(保存不要)
- ラベルは必ず「〜する」の肯定文で書く
- ラベルをクリックしてもチェックが切り替わること(
<label>で囲む)
5. 状態設計(States)
5.1 必須状態(Required)
- Unchecked:空の四角形。選択待ち
- Checked:✓が入り背景色が塗られた状態
- Focus:フォーカスリングを四角形の周囲に表示(省略不可)
- Disabled:チェックの有無にかかわらず全体をグレーアウト
5.2 条件付き状態(Conditional)
- Indeterminate:「全選択」の親Checkboxで子要素の一部が選択されている状態(横線「—」)
- Error:必須チェックが欠けている場合。枠・ラベル周辺を赤くしメッセージを表示
5.3 State Gallery
| 状態 | 必須 | 何を伝えるか |
|---|---|---|
| Unchecked | ✅ | 未選択であることを示す |
| Checked | ✅ | 選択済みであることを示す |
| Focus | ✅ | 今ここにいることをキーボードユーザーに示す |
| Disabled | ✅ | 今は操作できないことを示す |
| Indeterminate | — | 子要素の一部が選択されていることを示す |
| Error | — | 必須チェックが欠けていることを伝える |
6. バリエーション設計(Variants)
見た目ではなく「複数選択か / 即時反映か」でコンポーネントを選ぶ。
| 用途 | コンポーネント | 理由 |
|---|---|---|
| 複数選択・保留型 | Checkbox | 0個以上を選択し、送信で確定 |
| 排他選択 | Radio Button | 必ず1つだけ選択 |
| 即時反映 | Toggle Switch | 押した瞬間に設定変更 |
禁止パターン:排他選択(どちらか一方のみ)にCheckboxを使う → ユーザーが両方チェックできてしまう
併用の指針:「全て選択」Checkboxを使う場合は Indeterminate 状態を必ず実装する
7. パターン集(Good / Bad / How to fix)
7.0 よく崩れる設計パターン(3つ)
- Toggleとの混同:Checkboxを押した瞬間にシステム設定が即座に反映される(保存ボタンが必要なのにToggle扱いになっている)
- ヒット領域の極小化:16×16pxの四角だけがクリック可能で、ラベルの文字を押しても反応しない
- 排他選択への誤用:「A か B のどちらか」をCheckboxで実装してしまい、両方チェックできてしまう
7.1 Bad(典型3つ)
- ラベルが「メールによる通知を受信しない」→ チェックを入れるべきか外すべきか直感で判断できない
<input type="checkbox">と<label>が紐付いておらず、文字をクリックしても反応しない- 「全て選択」チェックボックスがあるが、一部選択時に Indeterminate にならずCheckedになってしまう
7.2 Good(対になる3つ)
- ラベルを「メールによる通知を受け取る」と肯定文に変更 → 迷いゼロ
<label>でCheckboxとテキストを丸ごと囲む → どこを押しても反応する- 一部選択時に
element.indeterminate = trueを設定 → 全選択の状態が正確に伝わる
7.3 How to fix(手順)
- ラベルの文言を「〜する」という肯定文に書き換える
<input id="chk1">と<label for="chk1">が正しく紐付いているか確認する- 排他選択(どちらか1つ)になっていないか確認 → なっていれば Radio に変更する
- 「全て選択」がある場合は Indeterminate の実装を追加する
7.4 GUNJO 実装で見る(Bad / Good)
同じ GUNJO の Checkbox を、ラベル関連付けの崩れた使い方と正しい使い方で対比。
8. ルール(Must / Better)
Must(守らないと壊れる)
Better(品質が跳ねる)
9. アクセシビリティ要件(必須)
Keyboard
Tabでフォーカスし、SpaceでChecked / Uncheckedを切り替えられること
Focus
- チェックボックスの周囲に明確なフォーカスリングを表示する
Screen Reader
<input type="checkbox">と<label>を正しく構造化し、項目名とチェック状態が読み上げられること- グループ化されたCheckbox群は
<fieldset>と<legend>で見出しを囲う
<fieldset>
<legend>通知設定</legend>
<label>
<input type="checkbox" name="email" /> メールで通知を受け取る
</label>
<label>
<input type="checkbox" name="push" /> プッシュ通知を受け取る
</label>
</fieldset>
Touch / Pointer
- CheckboxとラベルをセットにしてタップHit領域を最低44×44px確保する
10. 実装メモ(Implementation Notes)
- Indeterminate 状態はHTML属性では設定できない。
element.indeterminate = trueをJavaScript(またはReactのref)で設定する - React では
ref={(el) => { if (el) el.indeterminate = someChecked; }}のパターンが標準的 disabled+checkedの組み合わせは「変更不可の選択済み」を示す。読み取り専用フォームでの表示に使う
11. 関連リンク
- 関連するUIデザイン原則: アフォーダンス (Affordance), Fittsの法則 (Fitts's Law)
- 用語集(定義): アクセシビリティ (Accessibility)
- 関連するUIコンポーネント(横): Select(セレクト / プルダウンメニュー), Text Input(テキスト入力)
まとめ
Checkboxの設計は「複数選択可 + 保留型」という文法を守ることで9割決まります。迷ったら 4. 設計判断の核 に戻り、排他選択ならRadio・即時反映ならToggle Switchへの切り替えを検討してください。ラベルを <label> で丸ごと囲んで「押し心地」を確保することが、体験向上の第一歩です。