「どちらか1つを選ぶ」ことの視覚的な強制力を保ち、ユーザーが全ての選択肢を一目で比較できる排他選択UI。
この記事を読むと、CheckboxやSelectとの使い分け・初期値設計・グループのA11y要件の判断が自分でできるようになります。
1. UI例(Preview / Live)
実装で見る(GunjoUI)
この部品を、デザインシステム GUNJO の実装で確かめられます。
2. 定義(Definition)
Radio Button(ラジオボタン)とは、複数の選択肢の中からユーザーに「必ず1つだけ(排他的)」を選ばせる入力部品。
近いUIとの違い:Checkboxは「複数選択可」、Selectは「選択肢が多い・省スペース重視」、Toggle Switchは「即時反映の2択オン/オフ」。
3. 使い分け(When to use / When NOT to use)
3.1 When to use
- 選択肢が 2〜5個程度で、全てを並べて比較させたい場合
- 選択肢が 相互に排他的(同時に成り立たない)場合
- 必ずどれかを選択しなければならない(必須回答)場合
- ユーザーが選択肢の内容を一覧して判断する必要がある場合
3.2 When NOT to use
- 複数選択を認める場合 → Checkboxを使う
- 選択肢が6つ以上、または動的に増減する場合 → Selectを使う
- 即時反映の設定オン/オフ → Toggle Switchを使う
- 選択を必須にできない場合(未選択を許容したい場合)
3.3 代替UI(Alternatives)
- 選択肢が多い・省スペースが必要 → Select(セレクト / プルダウンメニュー)
- 複数選択が必要 → Checkbox(チェックボックス)
4. 設計判断の核(Decision Principles)
「丸(○)は1グループにつき1つしか埋まらない」というアフォーダンスを死守する。
- 全選択肢を露出させる: Radioの強みは「比較しながら1つに絞る意思決定アシスト」。隠してはならない
- 初期値を必ず設ける: 未選択状態はRadioの設計バグ。最も安全・一般的な選択肢をあらかじめCheckedにする
- 選択肢数で判断: 2〜5個 → Radio、6個以上 → Select、複数可 → Checkbox
- 未選択に戻す必要があるなら使わない: 標準仕様で「未選択に戻す」ができないため、その要件にはSelectや独自UIを選ぶ
5. 状態設計(States)
5.1 必須状態
- Unchecked(未選択): 空の円形。選択肢が存在することを示す
- Checked(選択済): 円形の中に塗りつぶされた小さな円(ドット)。唯一の選択であることを示す
- Focus(フォーカス): キーボード選択中。円の周囲に明確なアウトラインを表示する(必須)
- Disabled(無効): 操作不可。チェックの有無にかかわらずグレーアウトする
5.2 条件付き状態
- Error(エラー): 必須項目で未選択のまま送信しようとした状態。グループ全体を赤くハイライトし、エラーメッセージを表示する
5.3 State Gallery
| 状態 | 見た目 | 意図 |
|---|---|---|
| Unchecked | 空の円 | 選択可能 |
| Checked | 円+中央ドット | 選択済・排他確定 |
| Focus | 円+アウトライン | キーボード操作中 |
| Disabled | グレーアウト | 操作不可 |
| Error | 赤ハイライト+メッセージ | 必須未選択 |
6. バリエーション設計(Variants)
- 縦並び(基本): 各選択肢を1行ずつ縦に並べる。ラベルとの対応が明確で最も読みやすい
- 横並び(2〜3択のみ): 選択肢が2〜3個かつ短いラベルの場合のみ許容。間に十分な余白(gap-6以上)が必須
- カード型Radio: 選択肢全体をカードで囲み、選択状態をborderやbackgroundで表現する(説明文付きの選択に有効)
禁止パターン:横並びで5択以上・ラベルが長い・複数行にわたる横並び
7. パターン集(Good / Bad / How to fix)
7.0 よく崩れる設計パターン
- Checkboxとの混同: 排他選択にCheckbox(四角)を使う → ユーザーが複数選ぼうとしてエラーになる
- 未選択放置: 初期値なしで送信ボタンを表示 → フォームバリデーションエラーが直前まで検知できない
- 隠れた選択肢: 選択肢が多くてスクロールしないと見えない → ユーザーが全選択肢を知らずに決定する
7.1 Bad
- 「〇 男性 〇 女性 〇 その他」を隙間なく横並び → ラベルがどの丸のペアか一瞬迷う(ゲシュタルト崩壊)
- 必須項目なのに未選択のまま送信ボタンが押せる
7.2 Good
- 縦並びでグループ化。最も一般的な選択肢に初期チェックあり。ラベルの文字を押しても反応する。
<fieldset>/<legend>でグループが説明されている
7.3 How to fix
- 横並びにするなら選択肢間に
gap-6以上の余白を入れる - 最も標準的な選択肢を1つ決め
checked属性を初期付与する - 「未選択に戻す」が必要な要件ならSelectまたは「指定なし」をRadioの1択として追加する
7.4 GUNJO 実装で見る(Bad / Good)
同じ GUNJO の RadioGroup を、グループ/ラベルの崩れた使い方と正しい使い方で対比。
8. ルール(Must / Better)
Must(守らないと壊れる)
Better(品質が跳ねる)
9. アクセシビリティ要件(必須)
Keyboard
Tabでグループ内に入り、矢印キー(↑↓←→)で選択肢を移動・同時に値が切り替わる(標準挙動)- グループから抜けるには
Tabを使用する
Focus
- アクティブなRadioボタンにフォーカスリングを視認しやすく表示する
Screen Reader
- Radioボタン群全体を
<fieldset>で囲み、<legend>で「何を聞かれているか」を定義する - 個々の
role="radio"に対してaria-checkedとグループサイズが正しく読み上げられる(ネイティブ<input type="radio">を使えば自動)
Touch / Pointer
- ボタンとラベルを含む領域全体で最低 44×44px 相当のタップ領域を確保する
Contrast / Readability
- 選択済ドットと円背景のコントラスト比は 3:1以上を確保する
10. 実装メモ(Implementation Notes)
- React では
name属性で同一グループを束ねる。valueとcheckedをuseStateで管理する <fieldset>+<legend>はスクリーンリーダーでグループ名を読み上げるために必須。省略するとどの質問への回答か不明になる- カード型Radioを実装する場合、
<label>でカード全体を囲むことでタップ領域を最大化できる - Indeterminate 状態はRadioに存在しない(Checkboxと異なる)。グループ選択の概念がない
11. 関連リンク
- 関連するUIデザイン原則: アフォーダンス (Affordance), 選択の負担軽減 (Choice Reduction), 明確性と確実性 (Clarity & Certainty)
- 用語集(定義): アクセシビリティ (Accessibility), アフォーダンス (Affordance)
- 関連するUIコンポーネント(横): Checkbox(チェックボックス), Select(セレクト / プルダウンメニュー)
まとめ
Radio Buttonの設計は「排他選択かどうか」と「選択肢は何個か」で9割決まります。迷ったら 4. 設計判断の核 に戻り、初期値の有無とグループのA11y要件(fieldset / legend)を確認してください。「比較しながら1つに絞る」という体験を守ることがRadioの本質です。