【HTML】ラジオボタンの作り方:1つだけ選択・name・value・checked属性の設定

html-radio-button

フォームで「1つだけ選択」させるラジオボタンですが、グループ化やCSSでのデザイン変更にはコツが必要です。

本記事では、基本の書き方からCSSによるおしゃれなボタン風カスタマイズ、JavaScriptでの値の取得方法、アクセシビリティ対応まで解説します。

目次

ラジオボタンの基本と作り方

アンケートの性別や商品のカラー選択など、選択肢の中からどれか1つだけをユーザーに選ばせたい時に利用するのが ラジオボタンです。

チェックボックス(複数選択可)とは異なり、ラジオボタンは「1つだけ選択」させるUIパーツです。

しかし、HTMLを書いただけで自動的に「1つだけ」になるわけではありません。

ここでは、ラジオボタンを正しく機能させるグループ化の仕組みとスマホユーザーをイライラさせないテクニックを解説します。

ラジオボタンの基本と作り方
  • name属性によるグループ化の仕組みと重要性
  • labelタグを使ってクリック範囲を広げる方法

name属性によるグループ化の仕組みと重要性

ラジオボタンを作るタグは<input type="radio">です。

これ自体は丸いボタンを作るだけであり、複数並べただけではユーザーがポチポチと押していくと「全部のボタンが選択された状態」になります。

ラジオボタンを「どれか1つしか選べない状態」にするには、name属性を使ったグループ化が必要です。

1つの設問に関するラジオボタンには、同じname属性の値を設定してください。

そして、サーバーに「どれが選ばれたか」を伝えるために、ボタンには異なるvalue属性を持たせます。

❌ 悪い例(全部選べてしまうバグ)

お支払い方法(nameがバラバラ)

銀行振込
クレジットカード
コンビニ決済
<!– name属性が違うので、仲間として認識されない –>
<input type=”radio” name=”pay1″>
<input type=”radio” name=”pay2″>
<input type=”radio” name=”pay3″>

※全部ポチポチと押してみてください。1つだけ選ばせるつもりが、全部選べてしまいます。

⭕️ 良い例(同じnameで1つだけ選択)

お支払い方法(正しいグループ化)

銀行振込
クレジットカード
コンビニ決済
<!– 同じnameにして、グループ(仲間)にする –>
<!– サーバーに送るデータとしてvalueも必ず設定 –>
<input type=”radio” name=”payment” value=”bank”>
<input type=”radio” name=”payment” value=”card”>
<input type=”radio” name=”payment” value=”cvs”>

※こちらをクリックしてみてください。他のボタンを押すと、自動的に前の選択が外れて「必ず1つ」になります。

HTMLコード表示
<div class="hradio-group1-wrapper">
  
  <div class="hradio-group1-demo-area">
    
    <div class="hradio-group1-box">
      <div class="hradio-group1-label" style="color:#dc3545;">❌ 悪い例(全部選べてしまうバグ)</div>
      
      <div class="hradio-group1-visual">
        <p style="font-size:12px; font-weight:bold; color:#666; margin:0 0 10px 0;">お支払い方法(nameがバラバラ)</p>
        <div style="margin-bottom:5px;">
          <input type="radio" name="pay1" id="hradio-bad-1"> 銀行振込
        </div>
        <div style="margin-bottom:5px;">
          <input type="radio" name="pay2" id="hradio-bad-2"> クレジットカード
        </div>
        <div>
          <input type="radio" name="pay3" id="hradio-bad-3"> コンビニ決済
        </div>
      </div>

      <div class="hradio-group1-code hradio-group1-code-bad">
        <!-- name属性が違うので、仲間として認識されない --><br>
        <input type="radio" <span class="hradio-group1-hl-red">name="pay1"</span>><br>
        <input type="radio" <span class="hradio-group1-hl-red">name="pay2"</span>><br>
        <input type="radio" <span class="hradio-group1-hl-red">name="pay3"</span>>
      </div>
      <p class="hradio-group1-note">※全部ポチポチと押してみてください。1つだけ選ばせるつもりが、全部選べてしまいます。</p>
    </div>

    <div class="hradio-group1-box">
      <div class="hradio-group1-label" style="color:#198754;">⭕️ 良い例(同じnameで1つだけ選択)</div>
      
      <div class="hradio-group1-visual">
        <p style="font-size:12px; font-weight:bold; color:#333; margin:0 0 10px 0;">お支払い方法(正しいグループ化)</p>
        <div style="margin-bottom:5px;">
          <input type="radio" name="payment" value="bank" id="hradio-good-1" checked> 銀行振込
        </div>
        <div style="margin-bottom:5px;">
          <input type="radio" name="payment" value="card" id="hradio-good-2"> クレジットカード
        </div>
        <div>
          <input type="radio" name="payment" value="cvs" id="hradio-good-3"> コンビニ決済
        </div>
      </div>

      <div class="hradio-group1-code hradio-group1-code-good">
        <!-- 同じnameにして、グループ(仲間)にする --><br>
        <!-- サーバーに送るデータとしてvalueも必ず設定 --><br>
        <input type="radio" <span class="hradio-group1-hl-green">name="payment"</span> value="bank"><br>
        <input type="radio" <span class="hradio-group1-hl-green">name="payment"</span> value="card"><br>
        <input type="radio" <span class="hradio-group1-hl-green">name="payment"</span> value="cvs">
      </div>
      <p class="hradio-group1-note" style="color:#198754;">※こちらをクリックしてみてください。他のボタンを押すと、自動的に前の選択が外れて「必ず1つ」になります。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-group1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-group1-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  align-items: center;
}
.hradio-group1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hradio-group1-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hradio-group1-visual {
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #dee2e6;
  font-size: 14px;
  color: #333;
}
.hradio-group1-visual input[type="radio"] {
  cursor: pointer;
  transform: scale(1.2);
  margin-right: 5px;
}

.hradio-group1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hradio-group1-code-bad { border-left: 4px solid #dc3545; }
.hradio-group1-code-good { border-left: 4px solid #198754; }
.hradio-group1-hl-red { color: #e06c75; font-weight: bold; }
.hradio-group1-hl-green { color: #98c379; font-weight: bold; }
.hradio-group1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

inputタグの使い方を詳しく知りたい人は「【HTML】inputタグの使い方:type種類・属性一覧とCSS装飾・JS連携」を一読ください。

labelタグを使ってクリック範囲を広げる方法

ラジオボタンを画面に配置した時、使いやすさを大きく左右するのが<label>タグの活用です。

ラジオボタンの横に添える文字は、<label>タグで囲んでラジオボタンと紐付けます。

これにより、「文字の部分をクリックしても、ラジオボタンが選択される」というユーザーフレンドリーな動作になります。

紐付けの書き方には2種類あります。

  1. for属性とidを使う方法
    <input id="btn1">に対して<label for="btn1">と指定する。
  2. labelタグで丸ごと囲む方法
    <label><input type="radio"> 文字</label>
❌ 悪い例(丸ポチしか押せない)

↓文字をクリックしてみてください

男性
女性
<!– ただ並べただけでは、文字を押しても反応しない –>
<input type=”radio” name=”gender”> 男性
<input type=”radio” name=”gender”> 女性
⭕️ 良い例(文字を押しても選べる!)

↓文字をクリックしてみてください

<!– inputと文字を labelタグ で丸ごと囲む(一番簡単で確実) –>
<label>
  <input type=”radio” name=”gender”> 男性
</label>

※実務ではさらに、CSSで cursor: pointer; をつけてマウスを指のマークにし、「ここは押せるよ」とアピールします。

HTMLコード表示
<div class="hradio-label2-wrapper">
  
  <div class="hradio-label2-demo-area">
    
    <div class="hradio-label2-box">
      <div class="hradio-label2-label" style="color:#dc3545;">❌ 悪い例(丸ポチしか押せない)</div>
      
      <div class="hradio-label2-visual">
        <p style="font-size:12px; color:#666; margin:0 0 10px 0;">↓文字をクリックしてみてください</p>
        <div style="margin-bottom:10px;">
          <input type="radio" name="demo1"> 男性
        </div>
        <div>
          <input type="radio" name="demo1"> 女性
        </div>
      </div>

      <div class="hradio-label2-code hradio-label2-code-bad">
        <!-- ただ並べただけでは、文字を押しても反応しない --><br>
        <input type="radio" name="gender"> 男性<br>
        <input type="radio" name="gender"> 女性
      </div>
    </div>

    <div class="hradio-label2-box">
      <div class="hradio-label2-label" style="color:#198754;">⭕️ 良い例(文字を押しても選べる!)</div>
      
      <div class="hradio-label2-visual">
        <p style="font-size:12px; font-weight:bold; color:#333; margin:0 0 10px 0;">↓文字をクリックしてみてください</p>
        <div style="margin-bottom:10px;">
          <label class="hradio-label2-good-label">
            <input type="radio" name="demo2" checked> 男性
          </label>
        </div>
        <div>
          <label class="hradio-label2-good-label">
            <input type="radio" name="demo2"> 女性
          </label>
        </div>
      </div>

      <div class="hradio-label2-code hradio-label2-code-good">
        <!-- inputと文字を labelタグ で丸ごと囲む(一番簡単で確実) --><br>
        <span class="hradio-label2-hl-green"><label></span><br>
          <input type="radio" name="gender"> 男性<br>
        <span class="hradio-label2-hl-green"></label></span>
      </div>
      <p class="hradio-label2-note" style="color:#198754;">※実務ではさらに、CSSで <code>cursor: pointer;</code> をつけてマウスを指のマークにし、「ここは押せるよ」とアピールします。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-label2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-label2-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  align-items: center;
}
.hradio-label2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hradio-label2-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hradio-label2-visual {
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #dee2e6;
  font-size: 16px;
  color: #333;
}
.hradio-label2-visual input[type="radio"] {
  transform: scale(1.2);
  margin-right: 8px;
}

/* ⭕️ 良い例のlabelの装飾 */
.hradio-label2-good-label {
  display: inline-block;
  cursor: pointer; /* ★マウスを乗せた時に指のマークにする(実務必須) */
  padding: 5px 10px; /* 文字の周りにも少し余白を持たせて押しやすくする */
  background-color: #e9ecef;
  border-radius: 4px;
  transition: background-color 0.2s;
}
.hradio-label2-good-label:hover {
  background-color: #dee2e6; /* ホバーで少し色を変える親切設計 */
}

.hradio-label2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hradio-label2-code-bad { border-left: 4px solid #dc3545; }
.hradio-label2-code-good { border-left: 4px solid #198754; }
.hradio-label2-hl-green { color: #98c379; font-weight: bold; }
.hradio-label2-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

初期値(デフォルト)と選択状態の設定方法

アンケートフォームなどで画面を開いた瞬間に、「男性」や「無料プラン」にチェックが入っている状態を作ることは、ユーザーの入力の手間を省くテクニックです。

ここでは、ラジオボタンの選択状態をコントロールする属性の使い方とシステムの都合で「今は選べないようにする」設定について解説します。

初期値(デフォルト)と選択状態の設定方法
  • checked属性の使い方と動的に初期値を変える方法
  • 非活性で選択できないようにする

checked属性の使い方と動的に初期値を変える方法

ラジオボタンを最初から選択された状態にするには、<input>タグにchecked属性を記述するだけです。

HTMLにベタ書きでcheckedを固定するのではなく、「ユーザーが前回選んだ値とボタンの値が一致していたらcheckedという文字を出力する」という条件分岐のプログラムを書いて、動的に初期値をセットするのがよいです。

❌ 悪い例(複数のcheckedが競合)

希望プラン(Aを初期値にしたいのに…)

<input type=”radio” name=”plan” checked> A
<input type=”radio” name=”plan” checked> B
/* ⚠️ ブラウザは最後に書かれたBを優先してしまい、Aの初期値設定が壊れます */
⭕️ 良い例(プログラムで動的に付与)

希望プラン(エラーで戻ってきても保持)

↑ ユーザーが前回Bを選んでいた場合、Bに自動付与
<!– 💡 実務でのPHPの書き方イメージ –>
<input type=”radio” name=”plan” value=”A”
  <?php if($selected == ‘A’) echo ‘checked’; ?>> A

<input type=”radio” name=”plan” value=”B”
  <?php if($selected == ‘B’) echo ‘checked’; ?>> B

※このようにプログラムで判定することで、常に正しい1箇所だけに checked が入るように制御します。

HTMLコード表示
<div class="hradio-state1-wrapper">
  
  <div class="hspan-state1-demo-area">
    
    <div class="hradio-state1-box">
      <div class="hradio-state1-label" style="color:#dc3545;">❌ 悪い例(複数のcheckedが競合)</div>
      
      <div class="hradio-state1-visual">
        <p style="font-size:12px; color:#666; margin:0 0 10px 0;">希望プラン(Aを初期値にしたいのに…)</p>
        <label style="margin-right: 15px; cursor: pointer;">
          <input type="radio" name="plan_bad" checked> プランA
        </label>
        <label style="cursor: pointer;">
          <input type="radio" name="plan_bad" checked> プランB
        </label>
      </div>

      <div class="hradio-state1-code hradio-state1-code-bad">
        <input type="radio" name="plan" <span class="hradio-state1-hl-red">checked</span>> A<br>
        <input type="radio" name="plan" <span class="hradio-state1-hl-red">checked</span>> B<br>
        /* ⚠️ ブラウザは最後に書かれたBを優先してしまい、Aの初期値設定が壊れます */
      </div>
    </div>

    <div class="hradio-state1-box">
      <div class="hradio-state1-label" style="color:#198754;">⭕️ 良い例(プログラムで動的に付与)</div>
      
      <div class="hradio-state1-visual">
        <p style="font-size:12px; font-weight:bold; color:#333; margin:0 0 10px 0;">希望プラン(エラーで戻ってきても保持)</p>
        <label style="margin-right: 15px; cursor: pointer;">
          <input type="radio" name="plan_good" value="A"> プランA
        </label>
        <label style="cursor: pointer;">
          <input type="radio" name="plan_good" value="B" checked> プランB
        </label>
        <div style="font-size:11px; color:#198754; margin-top:5px;">↑ ユーザーが前回Bを選んでいた場合、Bに自動付与</div>
      </div>

      <div class="hradio-state1-code hradio-state1-code-good">
        <!-- 💡 実務でのPHPの書き方イメージ --><br>
        <input type="radio" name="plan" value="A"<br>
          <span class="hradio-state1-hl-pink"><?php if($selected == 'A') echo 'checked'; ?></span>> A<br><br>
        <input type="radio" name="plan" value="B"<br>
          <span class="hradio-state1-hl-pink"><?php if($selected == 'B') echo 'checked'; ?></span>> B
      </div>
      <p class="hradio-state1-note" style="color:#198754;">※このようにプログラムで判定することで、常に正しい1箇所だけに <code>checked</code> が入るように制御します。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-state1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hspan-state1-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center;
}
.hradio-state1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-state1-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hradio-state1-visual {
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #dee2e6;
  font-size: 14px;
  color: #333;
}

.hradio-state1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hradio-state1-code-bad { border-left: 4px solid #dc3545; }
.hradio-state1-code-good { border-left: 4px solid #198754; }
.hradio-state1-hl-red { color: #e06c75; font-weight: bold; }
.hradio-state1-hl-pink { color: #c678dd; font-weight: bold; }
.hradio-state1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

非活性で選択できないようにする

「ラジオボタンは表示しつつも押せないようにしたい」という場合に使用するのがdisabled属性です。

これを付与すると、ボタンがグレーアウトされ、ユーザーはクリック(選択)できなくなります。

ラジオボタンを押せなくするには disabled を使います。

もし「変更させたくないが、データはサーバーに送りたい」という場合は、disabledをつけるのではなくpointer-events: none;でクリックを禁止するか、画面に文字だけを表示して裏側に<input type="hidden">(隠しデータ)を仕込むのがよいです。

❌ 悪い例(readonlyは効かない)
↑readonlyをつけても普通にクリックできてしまいます!
<!– ⚠️ ラジオボタンに readonly は無効です –>
<input type=”radio” readonly> 特別プラン
⭕️ 良い例(disabledと文字のグレーアウト)
↑文字ごと薄くなっており、クリックできません。
<!– HTML:disabledをつける –>
<label class=”is-disabled”>
  <input type=”radio” disabled> 終了
</label>

/* CSS:文字の色も薄くして親切に */
.is-disabled {
  opacity: 0.5; /* 半透明にする */
  cursor: not-allowed; /* 禁止マークを出す */
}

※disabledの要素はデータ送信されないため、送信が必要な場合は別途 <input type="hidden"> を使います。

HTMLコード表示
<div class="hradio-state2-wrapper">
  
  <div class="hradio-state2-demo-area">
    
    <div class="hradio-state2-box">
      <div class="hradio-state2-label" style="color:#dc3545;">❌ 悪い例(readonlyは効かない)</div>
      
      <div class="hradio-state2-visual">
        <label style="cursor: pointer;">
          <input type="radio" name="demo_bad" readonly> キャンペーン特別プラン
        </label>
        <div style="font-size:11px; color:#dc3545; margin-top:5px;">↑readonlyをつけても普通にクリックできてしまいます!</div>
      </div>

      <div class="hradio-state2-code hradio-state2-code-bad">
        <!-- ⚠️ ラジオボタンに readonly は無効です --><br>
        <input type="radio" <span class="hradio-state2-hl-red">readonly</span>> 特別プラン
      </div>
    </div>

    <div class="hradio-state2-box">
      <div class="hradio-state2-label" style="color:#198754;">⭕️ 良い例(disabledと文字のグレーアウト)</div>
      
      <div class="hradio-state2-visual">
        <label class="hradio-state2-label-disabled">
          <input type="radio" name="demo_good" disabled> キャンペーン特別プラン(終了)
        </label>
        <div style="font-size:11px; color:#198754; margin-top:5px;">↑文字ごと薄くなっており、クリックできません。</div>
      </div>

      <div class="hradio-state2-code hradio-state2-code-good">
        <!-- HTML:disabledをつける --><br>
        <label class="is-disabled"><br>
          <input type="radio" <span class="hradio-state2-hl-green">disabled</span>> 終了<br>
        </label><br><br>
        /* CSS:文字の色も薄くして親切に */<br>
        .is-disabled {<br>
          <span class="hradio-state2-hl-green">opacity: 0.5;</span> /* 半透明にする */<br>
          <span class="hradio-state2-hl-green">cursor: not-allowed;</span> /* 禁止マークを出す */<br>
        }
      </div>
      <p class="hradio-state2-note" style="color:#198754;">※disabledの要素はデータ送信されないため、送信が必要な場合は別途 <code><input type="hidden"></code> を使います。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-state2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-state2-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center;
}
.hradio-state2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-state2-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hradio-state2-visual {
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #dee2e6;
  font-size: 14px;
  color: #333;
}

/* ⭕️ 良い例のdisabled装飾 */
.hradio-state2-label-disabled {
  display: inline-block;
  opacity: 0.5; /* 全体を薄くする */
  cursor: not-allowed; /* マウスを禁止マークにする */
}
.hradio-state2-label-disabled input {
  cursor: not-allowed;
}

.hradio-state2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hradio-state2-code-bad { border-left: 4px solid #dc3545; }
.hradio-state2-code-good { border-left: 4px solid #198754; }
.hradio-state2-hl-red { color: #e06c75; font-weight: bold; }
.hradio-state2-hl-green { color: #98c379; font-weight: bold; }
.hradio-state2-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

ラジオボタンのおしゃれなデザインと配置

ブラウザが標準で用意してるラジオボタンは、サイズが小さく、デザインもグレーや青のシンプルなものであるため、サイトの雰囲気に合わないことがあります。

CSSを駆使すれば、見た目のデザイン、画面上での配置までおしゃれにカスタマイズできます。

ここでは、実務で必須となるサイズの拡大やボタン風デザインへの変更、Flexboxを使ったレイアウト調整について解説します。

ラジオボタンのおしゃれなデザインと配置
  • ラジオボタンのサイズを大きくする・色を変える
  • 標準の丸を消して画像やボタン風に変更する

ラジオボタンのサイズを大きくする・色を変える

スマホユーザーにとって、標準のラジオボタンは小さすぎて押しにくいです。

そのため、ラジオボタンの大きさを広げ、サイトのテーマカラーに合わせて色を変えるのが基本のカスタマイズです。

ラジオボタンを大きくするには、transform: scale();を使用します。

また、選択された時の色を変えたい場合は、accent-colorプロパティを使うだけでテーマカラーに変更できます。

❌ 悪い例(font-sizeや背景色は完全に無視される)
input[type=”radio”] {
  font-size: 30px; /* ボタン自体は大きくならない! */
  background-color: #d63384; /* 色も変わらない! */
}
⭕️ 良い例(scaleで拡大・accent-colorで色変更)
input[type=”radio”] {
  transform: scale(1.5); /* 1.5倍に拡大 */
  accent-color: #d63384; /* ピンク色に変更 */
}

※この2行のCSSを追加するだけで、スマホでも格段に押しやすく、デザインに馴染むラジオボタンが作れます。

HTMLコード表示
<div class="hradio-design1-wrapper">
  
  <div class="hradio-design1-demo-area">
    
    <div class="hradio-design1-box">
      <div class="hradio-design1-label" style="color:#dc3545;">❌ 悪い例(font-sizeや背景色は完全に無視される)</div>
      
      <div class="hradio-design1-visual">
        <label style="cursor: pointer; display: flex; align-items: center;">
          <input type="radio" name="size_bad" class="hradio-design1-bad" checked> 
          <span>小さくて青い標準のまま(効いていない)</span>
        </label>
      </div>

      <div class="hradio-design1-code hradio-design1-code-bad">
        input[type="radio"] {<br>
          <span class="hradio-design1-hl-red">font-size: 30px;</span> /* ボタン自体は大きくならない! */<br>
          <span class="hradio-design1-hl-red">background-color: #d63384;</span> /* 色も変わらない! */<br>
        }
      </div>
    </div>

    <div class="hradio-design1-box">
      <div class="hradio-design1-label" style="color:#198754;">⭕️ 良い例(scaleで拡大・accent-colorで色変更)</div>
      
      <div class="hradio-design1-visual">
        <label style="cursor: pointer; display: flex; align-items: center; margin-bottom: 10px;">
          <input type="radio" name="size_good" class="hradio-design1-good" checked> 
          <span>ピンク色の1.5倍サイズ</span>
        </label>
        <label style="cursor: pointer; display: flex; align-items: center;">
          <input type="radio" name="size_good" class="hradio-design1-good"> 
          <span>こちらも同じサイズ</span>
        </label>
      </div>

      <div class="hradio-design1-code hradio-design1-code-good">
        input[type="radio"] {<br>
          <span class="hradio-design1-hl-green">transform: scale(1.5);</span> /* 1.5倍に拡大 */<br>
          <span class="hradio-design1-hl-green">accent-color: #d63384;</span> /* ピンク色に変更 */<br>
        }
      </div>
      <p class="hradio-design1-note" style="color:#198754;">※この2行のCSSを追加するだけで、スマホでも格段に押しやすく、デザインに馴染むラジオボタンが作れます。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-design1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-design1-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center;
}
.hradio-design1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-design1-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hradio-design1-visual {
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #dee2e6;
  font-size: 14px;
  color: #333;
}

/* ❌ 悪い例のラジオボタン(絶対に効かない指定) */
.hradio-design1-bad {
  font-size: 30px; /* 効かない */
  background-color: #d63384; /* 効かない */
  color: #d63384; /* 効かない */
  margin: 0 8px 0 0;
}

/* ⭕️ 良い例のラジオボタン */
.hradio-design1-good {
  transform: scale(1.5); /* ★確実に拡大される */
  accent-color: #d63384; /* ★色をピンクに変更 */
  margin: 0 8px 0 4px; /* 見た目のバランス調整 */
}

.hradio-design1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hradio-design1-code-bad { border-left: 4px solid #dc3545; }
.hradio-design1-code-good { border-left: 4px solid #198754; }
.hradio-design1-hl-red { color: #e06c75; font-weight: bold; }
.hradio-design1-hl-green { color: #98c379; font-weight: bold; }
.hradio-design1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

標準の丸を消して画像やボタン風に変更する

アンケートの選択肢が多い場合は「縦並び」、性別のように少ない場合は「横並び」にするなどラジオボタンの配置はレイアウトの基本です。

レイアウト調整は、display: flex;(Flexbox)に任せます。

ラジオボタンを囲む親要素の<div>に対してFlexboxを適用し、縦に並べたい時はflex-direction: column;、横に並べたい時はflex-direction: row;を指定します。

項目同士の隙間もgap: 15px;のように一括でコントロールできるため、メンテナンス性の高いコードになります。

📏 Flexboxによる縦横レイアウト

↕️ 縦並び(flex-direction: column)

↔️ 横並び(flex-direction: row)

<!– HTMLはどちらも同じ構造(brタグは不要!) –>
<div class=”group”>
  <label><input type=”radio”> 項目1</label>
  <label><input type=”radio”> 項目2</label>
</div>

/* ↕️ 縦に並べるCSS */
.group {
  display: flex;
  flex-direction: column; /* 縦方向に積む */
  gap: 15px; /* 項目同士の隙間 */
}

/* ↔️ 横に並べるCSS */
.group {
  display: flex;
  flex-direction: row; /* 横方向に並べる(省略可) */
  gap: 20px; /* 項目同士の隙間 */
}

※スマホ画面の時はメディアクエリ(@media)を使って、横並びを縦並びに切り替えるのが実務のレスポンシブ対応です。

HTMLコード表示
<div class="hradio-design3-wrapper">
  
  <div class="hradio-design3-demo-area">
    
    <div class="hradio-design3-box">
      <div class="hradio-design3-label">📏 Flexboxによる縦横レイアウト</div>
      
      <div class="hradio-design3-visual">
        <p style="font-size:12px; font-weight:bold; color:#666; margin:0 0 10px 0;">↕️ 縦並び(flex-direction: column)</p>
        
        <div class="hradio-design3-flex-col">
          <label><input type="radio" name="dir1" checked> 10代</label>
          <label><input type="radio" name="dir1"> 20代</label>
          <label><input type="radio" name="dir1"> 30代</label>
        </div>
      </div>

      <div class="hradio-design3-visual">
        <p style="font-size:12px; font-weight:bold; color:#666; margin:0 0 10px 0;">↔️ 横並び(flex-direction: row)</p>
        
        <div class="hradio-design3-flex-row">
          <label><input type="radio" name="dir2" checked> 男性</label>
          <label><input type="radio" name="dir2"> 女性</label>
          <label><input type="radio" name="dir2"> その他</label>
        </div>
      </div>

      <div class="hradio-design3-code">
        <!-- HTMLはどちらも同じ構造(brタグは不要!) --><br>
        <div class="group"><br>
          <label><input type="radio"> 項目1</label><br>
          <label><input type="radio"> 項目2</label><br>
        </div><br><br>
        /* ↕️ 縦に並べるCSS */<br>
        .group {<br>
          <span class="hradio-design3-hl-green">display: flex;</span><br>
          <span class="hradio-design3-hl-green">flex-direction: column;</span> /* 縦方向に積む */<br>
          <span class="hradio-design3-hl-blue">gap: 15px;</span> /* 項目同士の隙間 */<br>
        }<br><br>
        /* ↔️ 横に並べるCSS */<br>
        .group {<br>
          <span class="hradio-design3-hl-green">display: flex;</span><br>
          <span class="hradio-design3-hl-green">flex-direction: row;</span> /* 横方向に並べる(省略可) */<br>
          <span class="hradio-design3-hl-blue">gap: 20px;</span> /* 項目同士の隙間 */<br>
        }
      </div>
      <p class="hradio-design3-note">※スマホ画面の時はメディアクエリ(@media)を使って、横並びを縦並びに切り替えるのが実務のレスポンシブ対応です。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-design3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-design3-demo-area {
  display: flex;
  justify-content: center;
}
.hradio-design3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-design3-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #198754; }

.hradio-design3-visual {
  padding: 20px;
  background-color: #f1f3f5;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* ★縦並びにするFlexbox */
.hradio-design3-flex-col {
  display: flex;
  flex-direction: column; /* 縦方向に要素を積む */
  gap: 12px; /* 縦の隙間を一括指定 */
}

/* ★横並びにするFlexbox */
.hradio-design3-flex-row {
  display: flex;
  flex-direction: row; /* 横方向に要素を並べる */
  gap: 25px; /* 横の隙間を一括指定 */
  flex-wrap: wrap; /* 画面が狭ければ折り返す安全設計 */
}

/* ラベルの調整 */
.hradio-design3-visual label {
  cursor: pointer;
  font-size: 14px;
  color: #333;
  display: flex;
  align-items: center; /* ラジオボタンと文字の縦のズレを直す */
}
.hradio-design3-visual input[type="radio"] {
  margin: 0 6px 0 0;
}

.hradio-design3-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hradio-design3-hl-green { color: #98c379; font-weight: bold; }
.hradio-design3-hl-blue { color: #61afef; font-weight: bold; }
.hradio-design3-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

displayプロパティの使い方を詳しく知りたい人は「【html&css】displayの種類は?flexやinline-blockの違い」を一読ください。

JavaScriptでラジオボタンの値を操作・取得

お問い合わせフォームのカスタマイズや料金シミュレーション機能などを作りたい場合、HTMLとCSSだけでは限界があります。

そこで必須になるのが、JavaScriptを使ってラジオボタンの操作を行うスキルです。

ここでは、どのボタンが選ばれたのかを特定して値を取得する方法、イベントを検知して画面を切り替えるテクニックを解説します。

JavaScriptでラジオボタンの値を操作・取得
  • 選択されている値を取得する方法
  • イベントを検知して処理を実行する
  • 選択による表示切替と選択解除

選択されている値を取得する方法

アンケートの満足度や性別など、ユーザーが選んだデータをJavaScriptで取得するには、<input>タグに設定されたvalue属性を読み取ります。

ラジオボタンは「同じnameのグループの中から、現在チェックされてるもの」を探し出す必要があります。

JavaScriptでは、document.querySelector('input[name="グループ名"]:checked').value;という1行を書くのが安全な値の取得方法です。

🔍 選択された値(value)の取得

満足度を教えてください

<!– ❌ 悪い例:idで直接valueを見にいく –>
const val = document.getElementById(‘bad-id-bad’).value;
// ⚠ チェック状態を無視して、常に’bad’が取れる!

<!– ⭕️ 良い例:nameと :checked を組み合わせて探す –>
const selected = document.querySelector(‘input[name=”satisfaction”]:checked’);
if (selected) {
  console.log(“選ばれた値は:” + selected.value);
}

※ラジオボタンの値取得に id は絶対に使わず、:checked 疑似クラスを使って「今選ばれているやつ」を指定しましょう。

HTMLコード表示
<div class="hradio-js1-wrapper">
  
  <div class="hradio-js1-demo-area">
    
    <div class="hradio-js1-box">
      <div class="hradio-js1-label">🔍 選択された値(value)の取得</div>
      
      <div class="hradio-js1-visual">
        <p style="font-size:12px; font-weight:bold; color:#666; margin:0 0 10px 0;">満足度を教えてください</p>
        <div style="margin-bottom:15px; display:flex; gap:15px;">
          <label style="cursor:pointer;"><input type="radio" name="satisfaction" value="good" id="bad-id-good" checked> 満足</label>
          <label style="cursor:pointer;"><input type="radio" name="satisfaction" value="normal" id="bad-id-normal"> 普通</label>
          <label style="cursor:pointer;"><input type="radio" name="satisfaction" value="bad" id="bad-id-bad"> 不満</label>
        </div>

        <div style="display:flex; gap:10px;">
          <button class="hradio-js1-btn-bad" onclick="alert('idで取得した値:' + document.getElementById('bad-id-bad').value + '\n※不満が選ばれていなくても、常に「bad」が取得されてしまう最悪のバグです!');">
            ❌ idで取得(バグ)
          </button>
          <button class="hradio-js1-btn-good" onclick="const selected = document.querySelector('input[name=\'satisfaction\']:checked'); if(selected){ alert('正しく取得した値:' + selected.value); } else { alert('何も選択されていません'); }">
            ⭕️ 正しい取得方法
          </button>
        </div>
      </div>

      <div class="hradio-js1-code">
        <!-- ❌ 悪い例:idで直接valueを見にいく --><br>
        const val = document.getElementById('bad-id-bad').<span class="hradio-js1-hl-red">value</span>;<br>
        <span class="hradio-js1-hl-red">// ⚠ チェック状態を無視して、常に'bad'が取れる!</span><br><br>
        <!-- ⭕️ 良い例:nameと :checked を組み合わせて探す --><br>
        const selected = document.<span class="hradio-js1-hl-green">querySelector</span>(<span class="hradio-js1-hl-blue">'input[name="satisfaction"]:checked'</span>);<br>
        if (selected) {<br>
          console.log("選ばれた値は:" + selected.<span class="hradio-js1-hl-green">value</span>);<br>
        }
      </div>
      <p class="hradio-js1-note">※ラジオボタンの値取得に <code>id</code> は絶対に使わず、<code>:checked</code> 疑似クラスを使って「今選ばれているやつ」を指定しましょう。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-js1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-js1-demo-area {
  display: flex;
  justify-content: center;
}
.hradio-js1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-js1-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #333; }

.hradio-js1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

.hradio-js1-btn-bad {
  flex: 1; padding: 10px; background-color: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; font-size: 12px;
}
.hradio-js1-btn-good {
  flex: 1; padding: 10px; background-color: #198754; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; font-size: 12px;
}

.hradio-js1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hradio-js1-hl-red { color: #e06c75; font-weight: bold; }
.hradio-js1-hl-green { color: #98c379; font-weight: bold; }
.hradio-js1-hl-blue { color: #61afef; font-weight: bold; }
.hradio-js1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

イベントを検知して処理を実行する

「ユーザーがラジオボタンを選択した瞬間に、合計金額を再計算して表示する」といった機能を作るには、JavaScriptのイベントを検知する仕組みが必要です。

ラジオボタンの状態変化を検知するには、changeイベントを使用します。

これにより、チェック状態が変わった瞬間だけを正確に捉えられます。

また、複数のラジオボタン全てにイベントを仕掛けるには、forEach構文などを使って1つずつイベントリスナーを登録する処理を書く必要があります。

⚡ changeイベントによるリアルタイム検知

お好みのフルーツは?

まだ選択されていません
// 1. name=”fruit” のラジオボタンを「すべて」取得
const radios = document.querySelectorAll(‘input[name=”fruit”]’);
const resultArea = document.getElementById(‘result’);

// 2. forEachを使って、1つずつにイベントを登録する
radios.forEach((radio) => {
  // ★clickではなく change を使う!
  radio.addEventListener(‘change’, function() {
    // 選択が「変わった」瞬間に、自身のvalueを表示する
    resultArea.textContent = this.value + ” が選ばれました!”;
  });
});
HTMLコード表示
<div class="hradio-js2-wrapper">
  
  <div class="hradio-js2-demo-area">
    
    <div class="hradio-js2-box">
      <div class="hradio-js2-label">⚡ changeイベントによるリアルタイム検知</div>
      
      <div class="hradio-js2-visual">
        <p style="font-size:12px; font-weight:bold; color:#666; margin:0 0 10px 0;">お好みのフルーツは?</p>
        <div style="margin-bottom:15px; display:flex; gap:15px;">
          <label style="cursor:pointer;"><input type="radio" name="fruit" value="🍎りんご" class="hradio-js2-target"> りんご</label>
          <label style="cursor:pointer;"><input type="radio" name="fruit" value="🍊みかん" class="hradio-js2-target"> みかん</label>
          <label style="cursor:pointer;"><input type="radio" name="fruit" value="🍇ぶどう" class="hradio-js2-target"> ぶどう</label>
        </div>

        <div id="hradio-js2-result" style="padding:10px; background-color:#e7f1ff; color:#0d6efd; font-weight:bold; border-radius:4px; text-align:center;">
          まだ選択されていません
        </div>
      </div>

      <div class="hradio-js2-code">
        // 1. name="fruit" のラジオボタンを「すべて」取得<br>
        const radios = document.querySelectorAll('input[name="fruit"]');<br>
        const resultArea = document.getElementById('result');<br><br>
        // 2. forEachを使って、1つずつにイベントを登録する<br>
        <span class="hradio-js2-hl-blue">radios.forEach(</span>(radio) => {<br>
          // ★clickではなく change を使う!<br>
          radio.addEventListener(<span class="hradio-js2-hl-green">'change'</span>, function() {<br>
            // 選択が「変わった」瞬間に、自身のvalueを表示する<br>
            resultArea.textContent = <span class="hradio-js2-hl-pink">this.value</span> + " が選ばれました!";<br>
          });<br>
        <span class="hradio-js2-hl-blue">});</span>
      </div>
    </div>

  </div>
</div>
CSSコード表示
.hradio-js2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-js2-demo-area {
  display: flex;
  justify-content: center;
}
.hradio-js2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-js2-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #198754; }

.hradio-js2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

.hradio-js2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hradio-js2-hl-green { color: #98c379; font-weight: bold; }
.hradio-js2-hl-blue { color: #61afef; font-weight: bold; }
.hradio-js2-hl-pink { color: #c678dd; font-weight: bold; }
JavaScriptコード表示
// サンプル用のJS挙動
const js2Radios = document.querySelectorAll('.hradio-js2-target');
const js2Result = document.getElementById('hradio-js2-result');

js2Radios.forEach((radio) => {
  radio.addEventListener('change', function() {
    js2Result.textContent = this.value + " が選ばれました!";
  });
});

選択による表示切替と選択解除

お問い合わせフォームでご職業のラジオボタンでその他を選んだ時だけ、具体的な職業を入力するテキストボックスが出現する仕組みがあります。

また、ラジオボタンは一度選ぶと外せない仕様ですが、「どうしても再度クリックで選択解除できるようにしてほしい」という特殊な要望が来ることもあります。

もし未選択に戻す機能が必要なら、無理にJSを書くのではなく、最初から「選択しない」というラジオボタンの選択肢を用意するのがUI/UXとして正解であり、システム的にも安全です。

※どうしても実装しなければならない場合は、前回の選択状態を変数に保持しておき、clickイベントで判定してchecked = falseにするというハックを用います。

🪄 「その他」での表示切替と、安全な解除UI

どこで当店を知りましたか?

// 1. ラジオボタンと隠しエリアを取得
const radios = document.querySelectorAll(‘input[name=”source”]’);
const otherWrap = document.getElementById(‘other-wrap’);

// 2. 状態が変わるたびに判定する
radios.forEach((radio) => {
  radio.addEventListener(‘change’, function() {
    if (this.value === ‘other’) {
      // 「その他」なら表示
      otherWrap.style.display = ‘block’;
    } else {
      // それ以外なら隠す
      otherWrap.style.display = ‘none’;
    }
  });
});

※「選択を外したい」という要望には、JSでハックするより「未選択に戻す用」のボタンを最初から置いておく方が、バグも起きずユーザーにも親切です。

HTMLコード表示
<div class="hradio-js3-wrapper">
  
  <div class="hradio-js3-demo-area">
    
    <div class="hradio-js3-box">
      <div class="hradio-js3-label">🪄 「その他」での表示切替と、安全な解除UI</div>
      
      <div class="hradio-js3-visual">
        <p style="font-size:12px; font-weight:bold; color:#666; margin:0 0 10px 0;">どこで当店を知りましたか?</p>
        
        <div style="display:flex; flex-wrap:wrap; gap:10px; margin-bottom:15px;">
          <label style="cursor:pointer;"><input type="radio" name="source" value="none" class="hradio-js3-toggle" checked> 特にない(未選択)</label>
          <label style="cursor:pointer;"><input type="radio" name="source" value="web" class="hradio-js3-toggle"> ネット検索</label>
          <label style="cursor:pointer;"><input type="radio" name="source" value="other" class="hradio-js3-toggle"> その他</label>
        </div>

        <div id="hradio-js3-other-wrap" style="display:none; padding:10px; background-color:#fff; border:1px solid #ccc; border-radius:4px;">
          <label style="font-size:12px; color:#333; display:block; margin-bottom:5px;">「その他」の詳細を入力してください:</label>
          <input type="text" placeholder="例:知人の紹介" style="width:100%; padding:8px; box-sizing:border-box;">
        </div>
      </div>

      <div class="hradio-js3-code">
        // 1. ラジオボタンと隠しエリアを取得<br>
        const radios = document.querySelectorAll('input[name="source"]');<br>
        const otherWrap = document.getElementById('other-wrap');<br><br>
        // 2. 状態が変わるたびに判定する<br>
        radios.forEach((radio) => {<br>
          radio.addEventListener('change', function() {<br>
            if (<span class="hradio-js3-hl-pink">this.value === 'other'</span>) {<br>
              // 「その他」なら表示<br>
              otherWrap.style.<span class="hradio-js3-hl-blue">display = 'block'</span>;<br>
            } else {<br>
              // それ以外なら隠す<br>
              otherWrap.style.<span class="hradio-js3-hl-blue">display = 'none'</span>;<br>
            }<br>
          });<br>
        });
      </div>
      <p class="hradio-js3-note">※「選択を外したい」という要望には、JSでハックするより「未選択に戻す用」のボタンを最初から置いておく方が、バグも起きずユーザーにも親切です。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-js3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-js3-demo-area {
  display: flex;
  justify-content: center;
}
.hradio-js3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-js3-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #d63384; }

.hradio-js3-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

.hradio-js3-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #d63384;
}
.hradio-js3-hl-pink { color: #c678dd; font-weight: bold; }
.hradio-js3-hl-blue { color: #61afef; font-weight: bold; }
.hradio-js3-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }
JavaScriptコード表示
// サンプル用のJS挙動(表示切替)
const js3Radios = document.querySelectorAll('.hradio-js3-toggle');
const js3Wrap = document.getElementById('hradio-js3-other-wrap');

js3Radios.forEach((radio) => {
  radio.addEventListener('change', function() {
    if (this.value === 'other') {
      js3Wrap.style.display = 'block';
    } else {
      js3Wrap.style.display = 'none';
    }
  });
});

ラジオボタンのよくある疑問とトラブル解決

ラジオボタンを実装する際、想定通りに選択できない、あるいはユーザーにとって使い勝手が悪いといったトラブルはWeb制作の現場で頻発します。

ここでは、「複数選択されてしまうバグ」の解決方法とWeb制作で必須要件となっている「アクセシビリティ」を解説します。

ラジオボタンのよくある疑問とトラブル解決
  • 複数選択になってしまう時のチェックポイント
  • アクセシビリティに配慮したラジオボタンの作成

複数選択になってしまう時のチェックポイント

ラジオボタンの特徴は「排他制御(1つを選ぶと他が外れる)」ですが、コーディングをした後に「あれ?複数の項目が同時に選択できてしまう。」というバグに遭遇します。

複数選択のバグが起きたら、ブラウザの開発者ツールを開き、対象のラジオボタンのname属性の文字列が「完全に一致しているか」をハイライト検索して確認する癖をつけましょう。

❌ 悪い例(複数選択できてしまう)

希望のカラー

<!– ⚠️ name属性がバラバラになっている! –>
<input type=”radio” name=”color_red”> 赤
<input type=”radio” name=”color_blue”> 青
<input type=”radio” name=”color_green”> 緑

※全部クリックできてしまいます。これは「ラジオボタン」の形をした別々の入力欄として認識されているためです。

⭕️ 良い例(1つしか選択できない)

希望のカラー

<!– 💡 name属性を完全に一致させ、値の違いはvalueで出す –>
<input type=”radio” name=”item_color” value=”red”> 赤
<input type=”radio” name=”item_color” value=”blue”> 青
<input type=”radio” name=”item_color” value=”green”> 緑
HTMLコード表示
<div class="hradio-trouble1-wrapper">
  
  <div class="hradio-trouble1-demo-area">
    
    <div class="hradio-trouble1-box">
      <div class="hradio-trouble1-label" style="color:#dc3545;">❌ 悪い例(複数選択できてしまう)</div>
      
      <div class="hradio-trouble1-visual">
        <p style="font-size:12px; font-weight:bold; color:#666; margin:0 0 10px 0;">希望のカラー</p>
        <div style="display:flex; gap:15px;">
          <label style="cursor:pointer;"><input type="radio" name="color_red"> 赤</label>
          <label style="cursor:pointer;"><input type="radio" name="color_blue"> 青</label>
          <label style="cursor:pointer;"><input type="radio" name="color_green"> 緑</label>
        </div>
      </div>

      <div class="hradio-trouble1-code hradio-trouble1-code-bad">
        <!-- ⚠️ name属性がバラバラになっている! --><br>
        <input type="radio" <span class="hradio-trouble1-hl-red">name="color_red"</span>> 赤<br>
        <input type="radio" <span class="hradio-trouble1-hl-red">name="color_blue"</span>> 青<br>
        <input type="radio" <span class="hradio-trouble1-hl-red">name="color_green"</span>> 緑
      </div>
      <p class="hradio-trouble1-note">※全部クリックできてしまいます。これは「ラジオボタン」の形をした別々の入力欄として認識されているためです。</p>
    </div>

    <div class="hradio-trouble1-box">
      <div class="hradio-trouble1-label" style="color:#198754;">⭕️ 良い例(1つしか選択できない)</div>
      
      <div class="hradio-trouble1-visual">
        <p style="font-size:12px; font-weight:bold; color:#333; margin:0 0 10px 0;">希望のカラー</p>
        <div style="display:flex; gap:15px;">
          <label style="cursor:pointer;"><input type="radio" name="item_color" value="red" checked> 赤</label>
          <label style="cursor:pointer;"><input type="radio" name="item_color" value="blue"> 青</label>
          <label style="cursor:pointer;"><input type="radio" name="item_color" value="green"> 緑</label>
        </div>
      </div>

      <div class="hradio-trouble1-code hradio-trouble1-code-good">
        <!-- 💡 name属性を完全に一致させ、値の違いはvalueで出す --><br>
        <input type="radio" <span class="hradio-trouble1-hl-green">name="item_color"</span> value="red"> 赤<br>
        <input type="radio" <span class="hradio-trouble1-hl-green">name="item_color"</span> value="blue"> 青<br>
        <input type="radio" <span class="hradio-trouble1-hl-green">name="item_color"</span> value="green"> 緑
      </div>
    </div>

  </div>
</div>
CSSコード表示
.hradio-trouble1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-trouble1-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center;
}
.hradio-trouble1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-trouble1-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hradio-trouble1-visual {
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #dee2e6;
  font-size: 14px;
  color: #333;
}

.hradio-trouble1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hradio-trouble1-code-bad { border-left: 4px solid #dc3545; }
.hradio-trouble1-code-good { border-left: 4px solid #198754; }
.hradio-trouble1-hl-red { color: #e06c75; font-weight: bold; }
.hradio-trouble1-hl-green { color: #98c379; font-weight: bold; }
.hradio-trouble1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

アクセシビリティに配慮したラジオボタンの作成

Web開発では、「見た目が綺麗ならOK」という考え方は残念ながら通用しません。

マウスを使えないユーザーや画面が見えずに音声読み上げソフトを利用するユーザーにとっても使いやすい「アクセシビリティ」への配慮が必須です。

質問文と一連のラジオボタンを意味的に結びつけるには、<fieldset>(フィールドセット)タグで全体を囲み、質問文を<legend>(レジェンド)タグで記述します。

こうすることで、読み上げソフトは質問と回答をセットにして正しくユーザーに伝えてくれます。

また、キーボード操作で選択された際に、どこにフォーカスが当たっているかを視覚的に分かりやすくする:focus-visibleの設定も重要です。

❌ 悪い例(読み上げソフトが混乱する)

Q. 当サイトは使いやすいですか?

<!– ⚠️ 見た目は良いが、質問と選択肢に繋がりがない –>
<div class=”question-group”>
  <p>Q. 当サイトは使いやすいですか?</p>
  <label><input type=”radio” name=”q1″> はい</label>
</div>
⭕️ 良い例(fieldsetとlegendを使う)
Q. 当サイトは使いやすいですか?
<!– 💡 質問と選択肢をセットにする意味的なタグ –>
<fieldset>
  <legend>Q. 当サイトは使いやすいですか?</legend>
  <label><input type=”radio” name=”q1″> はい</label>
</fieldset>

※上の良い例のラジオボタンをクリックした後、キーボードの「矢印キー(→ や ←)」を押してみてください。キーボード操作でも切り替えられるのが正しいラジオボタンの仕様です。

HTMLコード表示
<div class="hradio-trouble2-wrapper">
  
  <div class="hradio-trouble2-demo-area">
    
    <div class="hradio-trouble2-box">
      <div class="hradio-trouble2-label" style="color:#dc3545;">❌ 悪い例(読み上げソフトが混乱する)</div>
      
      <div class="hradio-trouble2-visual">
        <p class="hradio-trouble2-q-text">Q. 当サイトは使いやすいですか?</p>
        <div style="display:flex; gap:10px;">
          <label><input type="radio" name="usability_bad"> はい</label>
          <label><input type="radio" name="usability_bad"> いいえ</label>
        </div>
      </div>

      <div class="hradio-trouble2-code hradio-trouble2-code-bad">
        <!-- ⚠️ 見た目は良いが、質問と選択肢に繋がりがない --><br>
        <div class="question-group"><br>
          <span class="hradio-trouble2-hl-red"><p></span>Q. 当サイトは使いやすいですか?<span class="hradio-trouble2-hl-red"></p></span><br>
          <label><input type="radio" name="q1"> はい</label><br>
        </div>
      </div>
    </div>

    <div class="hradio-trouble2-box">
      <div class="hradio-trouble2-label" style="color:#198754;">⭕️ 良い例(fieldsetとlegendを使う)</div>
      
      <fieldset class="hradio-trouble2-visual hradio-trouble2-fieldset">
        <legend class="hradio-trouble2-q-text hradio-trouble2-legend">Q. 当サイトは使いやすいですか?</legend>
        <div style="display:flex; gap:10px;">
          <label><input type="radio" name="usability_good" class="hradio-trouble2-a11y-radio"> はい</label>
          <label><input type="radio" name="usability_good" class="hradio-trouble2-a11y-radio"> いいえ</label>
        </div>
      </fieldset>

      <div class="hradio-trouble2-code hradio-trouble2-code-good">
        <!-- 💡 質問と選択肢をセットにする意味的なタグ --><br>
        <span class="hradio-trouble2-hl-green"><fieldset></span><br>
          <span class="hradio-trouble2-hl-green"><legend></span>Q. 当サイトは使いやすいですか?<span class="hradio-trouble2-hl-green"></legend></span><br>
          <label><input type="radio" name="q1"> はい</label><br>
        <span class="hradio-trouble2-hl-green"></fieldset></span>
      </div>
      <p class="hradio-trouble2-note" style="color:#198754;">※上の良い例のラジオボタンをクリックした後、キーボードの「矢印キー(→ や ←)」を押してみてください。キーボード操作でも切り替えられるのが正しいラジオボタンの仕様です。</p>
    </div>

  </div>
</div>
CSSコード表示
.hradio-trouble2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hradio-trouble2-demo-area {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: center;
}
.hradio-trouble2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hradio-trouble2-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hradio-trouble2-visual {
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #dee2e6;
  font-size: 14px;
  color: #333;
  box-sizing: border-box;
}
.hradio-trouble2-q-text {
  font-size: 13px;
  font-weight: bold;
  color: #333;
  margin: 0 0 10px 0;
  padding: 0;
}

.hradio-trouble2-fieldset {
  border: 1px solid #dee2e6; 
  margin: 0 0 15px 0;
  width: 100%;
}
.hradio-trouble2-legend {
  display: block;
  width: 100%;
  margin: 0 0 10px 0;
  padding: 0;
  border: none;
  line-height: 1.4;
}

/* キーボードフォーカス時の視覚的配慮(アクセシビリティ) */
.hradio-trouble2-a11y-radio:focus-visible {
  outline: 2px solid #0d6efd;
  outline-offset: 2px;
}

.hradio-trouble2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hradio-trouble2-code-bad { border-left: 4px solid #dc3545; }
.hradio-trouble2-code-good { border-left: 4px solid #198754; }
.hradio-trouble2-hl-red { color: #e06c75; font-weight: bold; }
.hradio-trouble2-hl-green { color: #98c379; font-weight: bold; }
.hradio-trouble2-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • 基本の役割
    複数の選択肢から「1つだけ」を選ばせる入力部品。
  • 排他制御(グループ化)
    同じ設問のラジオボタンには、全て同じname属性を設定する(バラバラだと複数選択される)。
  • データの設定
    サーバーにどの項目が選ばれたかを伝えるため、異なるvalue属性を設定する。
  • クリック範囲の拡大
    <label>タグでラジオボタンと文字を囲むことで、文字部分のクリックも選択可能になる。
  • 初期値の設定
    予め選択状態にするにはchecked属性を付与する。
  • 無効化(非活性)
    readonlyは効かないため、disabledを使用する(送信時にデータは送られない)。
  • サイズの拡大
    widthheightは避け、transform: scale()を使用して拡大する。
  • 標準カラーの変更
    accent-colorプロパティを使用して、テーマカラーに合わせた色に変更する。
  • ボタン風デザイン
    本体をopacity: 0position: absoluteで隠し、隣接セレクタ(:checked + span等)で装飾を切り替える(※display: noneは不可)。
  • レイアウト調整
    <br>による改行は避け、親要素にdisplay: flex(Flexbox)を使用して縦・横の並びを制御する。
  • JSでの値取得
    id指定はバグの元となるためdocument.querySelector('input[name="グループ名"]:checked').valueを使用する。
  • JSでのイベント検知
    状態変化を捉えるため、clickではなくchangeイベントを使用する。
  • アクセシビリティ
    読み上げソフト等のために、質問文と選択肢を<fieldset><legend>タグで囲み、意味的に関連付ける。

よくある質問(FAQ)

ラジオボタンで複数選択できてしまうのはなぜですか?

複数のラジオボタンのname属性の値が異なっているか、設定されていないことが原因です。

ブラウザは、同じname属性を持つラジオボタン同士を「1つのグループ」として認識し、その中で1つしか選べない仕様(排他制御)になっています。

同じ質問グループ内の全ての<input type="radio">に1文字の狂いもなく同じnameを指定してください。

ラジオボタンの文字をクリックしても選択できるようにするには?

<label>(ラベル)タグを使用します。

ラジオボタン(<input>)と横のテキストを<label></label>で丸ごと囲むだけで、文字部分をクリックしてもラジオボタンが選択されます。

スマートフォンの画面において、小さな丸ポチを正確にタップするのは困難なため、実務では必須の設定です。

最初から特定のラジオボタンを選択された状態にするには?

最初から選択状態にしておきたい<input type="radio">タグの中に、checkedという属性を書き足すだけです。

ただし、同じnameグループの中で複数のボタンにcheckedをつけてしまうと、ブラウザによって「最後に書かれたものが優先される」などのバグに繋がるため、グループ内で1箇所だけに設定してください。

一度選択したラジオボタンのチェックを外すことはできますか?

いいえ、HTMLの標準仕様では、一度選択したラジオボタンを再度クリックして未選択に戻すことはできません。

チェックボックスとは異なり、ラジオボタンは「どれか1つを選ぶ」ことに特化したUIです。

未選択状態に戻す機能が必要な場合は、「特に希望なし」というダミーのラジオボタンの選択肢を最初から用意しておくのが安全でユーザーに優しい解決策です。

選択されたラジオボタンの値をJavaScriptで取得するには?

JavaScriptでは、以下の1行で取得するのが簡単です。

document.querySelector('input[name="グループ名"]:checked').value;

初心者はgetElementByIdを使って取得しようとしがちですが、「現在選択されているかどうか」に関係なく値が取れるため、:checkedを使って「今チェックが入っている要素」を取得します。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次