HTML でラジオボタンを作る方法
ラジオボタンを使うと、読者はグループの中からちょうど 1 つの選択肢を選べます。各選択肢は <input type="radio"> で、同じ name を付けることでグループになります。サイズを選んで Order を押してみてください。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Radio buttons</title>
<style>
body { font-family: system-ui, sans-serif; }
fieldset { border: 1px solid #9ca3af; border-radius: 8px; }
label { display: block; margin: 4px 0; }
</style>
</head>
<body>
<form>
<fieldset>
<legend>Size</legend>
<label><input type="radio" name="size" value="s"> Small</label>
<label><input type="radio" name="size" value="m" checked> Medium</label>
<label><input type="radio" name="size" value="l"> Large</label>
</fieldset>
<p><button type="submit">Order</button></p>
</form>
</body>
</html>Master HTML the hands-on way
Interactive lessons, real projects, and instant feedback.
START NOW
フォームは size=m という 1 組を送ります。グループの name と、選択されたボタンの value です。各部分の役割です。
グループのすべてのボタンに同じ name を付けます。1 つを選ぶとほかの選択が外れます。
それぞれに別の value を付けます。サーバーが受け取るのはこの値です。value のないラジオボタンは on を送り、サーバーには何も伝わりません。
初期の選択肢に checked を付けます。
それぞれを <label> で囲んでテキストをクリックできるようにし、<fieldset> と <legend> でまとめて、スクリーンリーダーが各選択肢と一緒に質問 (「Size」) を読み上げるようにします。
グループを作るのは name
name の違うラジオボタンは別々のグループになり、グループごとに選択を持ちます。この例には 2 つのグループと、間違えてラジオボタンごとに別の name を付けてしまった壊れた組があります。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Radio groups</title>
<style>
body { font-family: system-ui, sans-serif; display: flex; flex-wrap: wrap; gap: 16px; }
fieldset { border: 1px solid #9ca3af; border-radius: 8px; }
.broken { border-color: #dc2626; }
label { display: block; margin: 4px 0; }
</style>
</head>
<body>
<fieldset>
<legend>Crust</legend>
<label><input type="radio" name="crust" value="thin" checked> Thin</label>
<label><input type="radio" name="crust" value="thick"> Thick</label>
</fieldset>
<fieldset>
<legend>Sauce</legend>
<label><input type="radio" name="sauce" value="tomato" checked> Tomato</label>
<label><input type="radio" name="sauce" value="pesto"> Pesto</label>
</fieldset>
<fieldset class="broken">
<legend>Broken: different names</legend>
<label><input type="radio" name="a" value="1"> One</label>
<label><input type="radio" name="b" value="2"> Two</label>
<label><input type="radio" name="c" value="3"> Three</label>
</fieldset>
</body>
</html>
壊れたグループの 3 つをすべてクリックしてみてください。すべて選択されたままになり、どれも外せません。最悪の組み合わせです。ラジオボタンは同じフォームの中で name によってグループになるので、2 つのフォームがそれぞれ name="size" のグループを持つこともできます。
必須のグループと初期選択なし
グループのどれか 1 つのラジオボタンに required を付けると、フォームを送信する前にどれかを選ぶ必要があります。checked を省くと読者が自分で選ぶことになり、妥当な初期値がないときにはこれが正解です。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Required radio group</title>
<style>
body { font-family: system-ui, sans-serif; }
fieldset { border: 1px solid #9ca3af; border-radius: 8px; }
label { display: block; margin: 4px 0; }
</style>
</head>
<body>
<form>
<fieldset>
<legend>How did you hear about us?</legend>
<label><input type="radio" name="source" value="search" required> Search engine</label>
<label><input type="radio" name="source" value="friend"> A friend</label>
<label><input type="radio" name="source" value="video"> A video</label>
<label><input type="radio" name="source" value="other"> Other</label>
</fieldset>
<p><button type="submit">Continue</button></p>
</form>
</body>
</html>
選ばずに Continue を押すと、ブラウザがメッセージを出して送信を止めます。どれか 1 つを選べば、グループ全体が有効になります。必須でないグループが何も選ばれていない場合は、チェックされていないチェックボックスと同じく何も送りません。
クリックでラジオボタンを選ぶことはできますが、選択を外すことはできません。一度選んだ後でも「回答なし」にできる必要があるなら、そのための選択肢を明示的に追加しましょう。
JavaScript で選択された値を読む
form.elements.name はグループ全体を返し、その .value は選択されたラジオボタンの値です (何も選ばれていなければ空文字列)。change イベントは、選択されたラジオボタンで発生します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Selected value</title>
<style>
body { font-family: system-ui, sans-serif; }
label { margin-inline-end: 12px; }
#price { font-size: 1.4em; font-weight: bold; color: #2563eb; }
</style>
</head>
<body>
<form id="billing">
<label><input type="radio" name="period" value="monthly" checked> Monthly</label>
<label><input type="radio" name="period" value="yearly"> Yearly</label>
</form>
<p>Price: <span id="price"></span></p>
<script>
const form = document.querySelector('#billing');
const prices = { monthly: '12 per month', yearly: '96 per year' };
const show = () => {
document.querySelector('#price').textContent = prices[form.elements.period.value];
};
form.addEventListener('change', show);
show();
</script>
</body>
</html>
リスナーはフォームに付けているので、どの入力欄の変化も捕まえます。フォームの外では、document.querySelector('input[name="period"]:checked') で選択されたラジオボタンを見つけます。
キーボード操作
ラジオボタンのグループは Tab キーの移動順で 1 か所として扱われます。Tab キーでグループに入ると選択されたラジオボタン (何も選ばれていなければ最初のもの) に移り、矢印キーで選択肢の間を移動します。もう一度 Tab キーを押すとグループから出ます。これは name を共有する本物のラジオボタンなら何もしなくても手に入る動作で、<div> 要素でラジオボタンを作り直すべきでない理由がまた 1 つ増えます。
ラジオボタンのデザイン
accent-color はブラウザ標準のラジオボタンの色を変えます。appearance: none を使うと自分で丸を描けます。そして、非表示のラジオボタンもラベルを通して選択できるので、ラジオボタンの動作をすべて残したまま、グループをカードの組のように見せることもできます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Radio styles</title>
<style>
body { font-family: system-ui, sans-serif; }
.accent { accent-color: #16a34a; }
.dot {
appearance: none;
width: 18px;
height: 18px;
margin: 0;
border: 2px solid #6b7280;
border-radius: 50%;
vertical-align: middle;
}
.dot:checked { border: 6px solid #2563eb; }
.dot:focus-visible { outline: 3px solid #f59e0b; outline-offset: 2px; }
.cards { display: flex; flex-wrap: wrap; gap: 8px; border: 0; padding: 0; margin: 16px 0 0; }
.card { display: block; padding: 10px 14px; border: 2px solid #e5e7eb; border-radius: 10px; cursor: pointer; }
.card input { position: absolute; opacity: 0; }
.card:has(input:checked) { border-color: #2563eb; background: #eff6ff; }
.card:has(input:focus-visible) { outline: 3px solid #f59e0b; outline-offset: 2px; }
</style>
</head>
<body>
<label><input type="radio" class="accent" name="c1" checked> accent-color</label>
<label><input type="radio" class="accent" name="c1"> accent-color</label>
<p>
<label><input type="radio" class="dot" name="c2" checked> Custom</label>
<label><input type="radio" class="dot" name="c2"> Custom</label>
</p>
<fieldset class="cards">
<legend>Plan</legend>
<label class="card"><input type="radio" name="plan" value="free" checked> Free</label>
<label class="card"><input type="radio" name="plan" value="pro"> Pro</label>
<label class="card"><input type="radio" name="plan" value="team"> Team</label>
</fieldset>
</body>
</html>
独自の丸は、チェックされたときに太い枠線になるだけです。カードでは input を display: none ではなく opacity: 0 で隠しているので、フォーカスでき、矢印キーも動きます。:has(input:checked) で選択されたカードにスタイルを付けています。:has() は現在の Chrome、Firefox、Safari で使えます。
ラジオボタン、チェックボックス、セレクトボックスの使い分け
使うもの 使う場面 ラジオボタン すべて見えているべき少数 (2 から 6 個程度) の選択肢から 1 つを選ぶ チェックボックス いくつでも選べる (0 個も含む) <select>国名のような長いリストから 1 つを選ぶ (HTML のセレクトボックス を参照)
よくある間違い
1 つのグループで name が違う。 どのラジオボタンも選択でき、どれも解除できなくなります。
value がない。 何を選んでもサーバーは on を受け取ります。
独自デザインで input を display: none で隠す。 フォーカスもキーボード操作もできなくなります。
<fieldset> と <legend> がない。 スクリーンリーダーは質問なしで「Small、ラジオボタン」と読み上げます。
「同意する」の箱にラジオボタンを 1 つだけ使う。 チェックを外せなくなります。チェックボックス を使いましょう。
1 つのグループの複数のラジオボタンに checked を付ける。 最後のものだけが選択されます。