HTMLを使って、ラジオボタンを実装する方法の解説です。HTMLのフォームを使って、実際にデータを送信する所までやってみます。
目次
ラジオボタンとは?
HTMLでの「ラジオボタン」とは、複数の選択肢の中からただ一つを選択(one of many)するためのGUIコンポーネントです。
ラジオボタンの例:
一方で、チェックボックスと役割が似て言いますが、チェックボックスは、「複数の中から、1つ以上選ぶか、なにも選ばない」と言う目的で利用する事が意図されています。
チェックボックスの例:
これらは、いずれも、通常は「フォーム」と呼ばれる、ユーザによる選択・入力情報を、サーバー上の特定のアドレスに送信を行うための機能の一部として利用されます。
ラジオボタンの名前の由来?
少し昔は、いわゆる「ラジオ」や「ラジカセ」というデバイスがまだ家庭にありました。その頃の、ラジカセのボタンは「複数ボタンがあっても、構造上、絶対に1つしか押せない」という仕組みで作られていました。当時はまだラジオボタンがイメージしやすかったですが、きっと現代に生まれた若者には全くピンとこない事でしょう。
ラジオボタンの基本的な実装
まずは、ラジオボタンを含むフォームのソースコードの基本サンプルからです。わかりやすさのため、HTML内にコメントを付けています。
<p>どちらにプロポーズしますか?</p> <form method="post" action="http://radio-button-sample.com/handler.php"> <!-- ラジオボタン選択肢 --> <input id="marry-b" type="radio" name="marry-to" value="bianca" checked> <label for="marry-b">ビアンカ</label> <!-- ラジオボタン選択肢 --> <input id="marry-f" type="radio" name="marry-to" value="flora"> <label for="marry-f">フローラ</label> <!-- 送信ボタン --> <input type="submit" value="プロポーズする"> </form>
コード自体はシンプルで、一度覚えてしまえば、以外に簡単なはずです。(少なくともビアンカとフローラのどちらかを選ぶよりはずっと簡単です [参考])
上記のコードだけでは、このような粗野な状態に実装されます。
See the Pen ラジオボタンのサンプル実装(初期) by Joe (@akajoe) on CodePen.0
form要素とinput要素に指定した属性を詳しく見ていきます。
form要素の属性
他にも幾つかform専用の属性が存在しますが、一般的なフォームで利用するのは下記の2つでしょう。
属性 | 取りうる値 | 意味 |
---|---|---|
method | GET, POST | フォームから送信するHTTPリクエストの種類です。通常は「POST」で送信するする事が多いですが、目的によっては「GET」でも構いません。 |
action | URL | フォームから送信する宛先のURLです。button要素や、input要素(submitタイプ)、formaction属性で上書きすることもできます。 |
input要素の属性
今回はラジオボタンですので、typeの値を「radio」とします。input要素はこのtype値によって、種々の機能をFormに与えることができます。
属性 | 取りうる値 | 意味 |
---|---|---|
type | radio, checkbox, text, submit, 他 |
フォーム内のinputのタイプを指定します。今回はラジオボタンなので「radio」と指定します。なお、「submit」はフォームの内容をactionに書かれたメソッドで、送信するボタンの役割を果たします。 |
name | 文字列 | 同じグループに含むラジオボタンに、同じname文字列を割り振ります。同じグループ内では、それぞれのラジオボタン要素の選択は、排他的になります。 |
id | 文字列 | あらゆるHTML要素共通の属性ですが、特に、ラジオボタンのfor属性と一致させることで、label要素をクリック可能にできます。 |
value | 送信する値 | このラジオボタンがチェックされたとき、送信される値です。labelのテキストでなく、このvalueの文字列が送信されることに注意します。 |
checked | なし | このラジオボタンがチェックされているかどうかです。checked属性が存在するかどうかで、値は必要ありません。 |
disabled | なし | この属性が存在すると、ラジオボタンが無効化され、選択できなくなります。checked属性が記載があれば値は必要ありません。 |
label要素の属性
labelは主にinput要素の名前をテキストで表示するために利用するHTML要素です。labelには「どのinput要素に向けられたものなのか」を指定するfor属性があります。
属性 | 取りうる値 | 意味 |
---|---|---|
for | 対応するinput要素のid | forで指定されたIDを持つinputがあれば、ラベル自体もクリック可能になります。 |
for属性は、対応するinput要素とラベルを紐付けるために必要ですが、labelでinputを囲むことにより、for属性による指定はなくても、対応が関連づけられ、labelのクリックが可能になります。
<label> <input type="radio" name="opt" value="a">選択肢A </label> <label> <input type="radio" name="opt" value="b">選択肢B </label>
CSSでレイアウトを整える
さて、上述のラジオボタンフォームのレイアウトを、CSSを駆使して整えていきます。まずはスタイリング例をご覧ください。
実装例がこちらです。
See the Pen ラジオボタンのサンプル実装(リッチ) by Joe (@akajoe) on CodePen.0
1fieldset で囲み、legend を追加する
fieldsetはフォーム内の関連する要素群をグルーピングすることができます。必須ではありませんが、特定の意味でグループを形成することに役立ちます。
同時にlegend要素を利用すれば、fieldsetの役割を記述することができます。各ブラウザはこのfieldsetとlegendの組み合わせのデフォルトスタイルを実装していますので、それを利用するのも悪くありません。
HTML構造をセマンティックに記載できますので、検索エンジンがフォームの内容を正しく理解するのにも、幾分役立つと考えられます。(実際にはどの程度効果があるか、わかりません)
Fieldset とLegend 要素のスタイリング
より詳細な独自デザインのスタイルを適応したい場合は、あえて、fieldsetとlegendのHTML要素を用いないほうが良いでしょう。これらはCSSの仕様を越えたブラウザ独自実装によるスタイリングが施されているため、CSSによるコントロールが行いにくくなっています。
例えば下記のように、fieldset と legend に関してブラウザごとの実装の違いによるスタイル調整の問題が指摘されています。
- https://stackoverflow.com/questions/29967730/how-to-get-cross-browser-form-fieldset-content-height-in-with-legend
- https://stackoverflow.com/questions/5339161/legend-tag-and-chrome
その場合、通常通り、sectionや、divでグルーピングし、h1などの見出しタグが、スタイリングにおいては利用しやすいでしょう。
2label で input を囲み、階層化する
スタイリングを行いやすくするため、ラジオボタンのinput要素を、labelで囲んでしまいました。これには、今回は下記のようなメリットがあります。
- labelにfor属性を振らなくても、ラベル文字列がクリック可能になる。
- labelとinput親子関係になるので、CSS上で、ネームスペース管理しやすい。
また、submitタイプのボタンも、見た目を調整するため、-webkit-appearanceを指定しています。これは主にchromeやsafariなどのブラウザで有効です。
3クラス名を割り振り、CSSでスタイリングする
CSSでネームスペース(*)を確保するため、form要素にクラス名「who-to-marry」を割り振っています。
下記のように、クラス名セレクタで限定することで、label、input要素のCSSから参照しやすくします。また、input[type=radio]と、属性のセレクタとして、利用していますが、単純にクラスを割り振っても構いません。
/* フォーム全体 */ .who-to-marry { } /* レジェンド */ .who-to-marry legend { } /* ラベル */ .who-to-marry legend label { } /* ラジオボタン */ .who-to-marry input[type=radio] { } /* 送信ボタン */ .who-to-marry input[type=submit] { } /* 送信ボタン(マウスオーバー) */ .who-to-marry input[type=submit]:hover{ }
さて、いくつかのポイントを補足します。
[3-1] label をブロック要素にして、縦並びに
labelは、デフォルトではインラインレベルの要素ですので、CSSで明示的にブロックにして、縦並びを実現します。
[3-2] ボタンのスタイリング
submit タイプのinput をスタイリングする際に、下記のプロパティを記述します。
input[type=submit] { appearance:none; display:block; outline:none; border:none; /* あとは好きに書く */ }
「appearance」はいわゆるブラウザUI部品のOSデザインを適応するための独自プロパティです。MacOSであればMacOSの、WindowであればWindowsが実装したGUIの見た目が適応されることになります。
これをいったんnoneにしてキャンセルしてやらないと、ブラウザが違ったときも意図通りのスタイリングが難しくなります。
CSSプロパティ「appearance 」はIEの対応が異なりますので、必要に応じて、テストしながら調整して下さい。
[3-3]ラジオボタンを縦方向に揃える
フォントサイズを調整すると、ラジオボタンが縦方向にずれて見えてしまう事がよくあります。フォントは大きくなっても、ラジオボタン自体が拡大されないからです。
これをCSSを使ってうまく縦方向の中央に寄せるには、ちょっとしたテクニックが必要です。
デフォルトラジオボタンの縦の中央寄せ
デフォルトのラジオボタン要素の縦方向の中央揃えの方法をこちらで詳しく紹介しています。
[3-4]ラジオボタンに画像を適応する
(こちらのセクションは、編集中です)
jQueryでフォーム送信イベントを制御する
submitタイプのボタンは、クリック時に「フォーム送信イベント」が発生し、ブラウザがこれを受け取ると、指定されたリクエストを送信します。
このイベントを「横取り」することで、間に処理を挟んだり、もしくは、ブラウザに処理を受け渡さない用にすることもできます。
下記にサンプル実装を添付します。ボタンを押すと、現在のフォームの状態をポップアップで表示します。
See the Pen ラジオボタンのサンプル実装(jQuery) by Joe (@akajoe) on CodePen.0
jQueryにおいて、フォーム送信イベントは、submitという名前で扱われていますが、フォーム要素のsubmitイベントがinput 要素から親要素にバブルアップしていきますので、これを横取りします。
フォーム要素の状態をデータ(JSON)に変換するには、serializeArray() メソッドを利用するのが一般的です。(逆にこれを使わないと結構面倒です。)
$('.who-to-marry').submit(function() { // フォームに対して連想配列を生成してくれるメソッド var values $(this).serializeArray(); // イベントを渡さず、ここでバブルアップを停止する。 return false; });
最後に「return false」を記載して、イベントを破棄します。これを記載すると、ブラウザはフォームデータを送信しません。不要であれば記載しないで下さい。
また、特定の任意のイベントに紐付けてフォーム送信を、submitボタン以外からも実行する事ができます。
$('.another-button').click(function() { $('.who-to-marry').submit(); });
jQueryでは、上記の例を知っておけば、フォーム周り基本的な実装は可能だと思います。
jQuery Document:
参考
加えて、チェックボックス版、記事です。