HTMLフォームのプルダウンにselected
属性を付けるべき理由
HTMLでフォームを作った際、プルダウンやリストボックスにdisabled
属性を設定したときの挙動がブラウザによって異なるのが興味深かったのでまとめてみます。
option
要素、optgroup
要素のdisabled
属性
input
要素やtextarea
要素などのフォームコントロールには、それを無効にするdisabled
属性があります。
変更を不可にするreadonly
属性と異なり、入力・選択ができなくなるだけでなく、フォーカスが合うことはなく、値の送信も行われません。たとえば次のフォームを送信した場合、 form.php には foo=hoge&baz=fuga しか送られません。
<form action="form.php">
<p><input name="foo" value="hoge" /></p>
<p><input name="bar" value="piyo" disabled="disabled" /></p>
<p><input name="baz" value="fuga" readonly="readonly" /></p>
<p><button type="submit">送信</button></p>
</form>
ところが、プルダウンやリストボックスの場合はdisabled
属性に対応していなかったり、挙動のおかしなブラウザが存在します。
option
要素に設定した場合、optgroup
要素に設定した場合など4パターンにてテストしてみます。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>プルダウンやリストボックスにdisabled属性を設定してみる</title>
</head>
<body>
<form action="">
<p>
<select name="s1" id="s1">
<option value="0" disabled="disabled">選択不能</option>
<option value="1">選択可</option>
</select>
<label for="s1">option要素にdisabled属性を設定</label>
</p>
<p>
<select name="s2" id="s2" multiple="multiple">
<option value="0" disabled="disabled">選択不能</option>
<option value="1">選択可</option>
</select>
<label for="s2">option要素にdisabled属性を設定(multiple)</label>
</p>
<p>
<select name="s3" id="s3">
<optgroup label="グループ1" disabled="disabled">
<option value="0">選択不能</option>
</optgroup>
<optgroup label="グループ2">
<option value="1">選択可</option>
</optgroup>
</select>
<label for="s3">optgroup要素にdisabled属性を設定</label>
</p>
<p>
<select name="s4" id="s4" disabled="disabled">
<option value="0">選択不能</option>
</select>
<label for="s4">select要素にdisabled属性を設定</label>
</p>
<p><button type="submit">送信</button></p>
</form>
</body>
</html>
このHTMLを、PCとスマートフォンの代表的なブラウザで表示させた場合の違いを表にしました。ただし、4つ目の「select
要素にdisabled
属性を設定」したものは、いずれのブラウザもコントロールごと無効になったので省略します。
Firefox13, IE8以降 | Chrome19 | Safari5.1 | Opera12 | iPhone, iPad | Android | |
---|---|---|---|---|---|---|
option 要素にdisabled 属性 |
disabled な選択肢は無効となり、有効なうち最初のものが初期選択 |
Fx, IEと同じ | 最初の選択肢がdisabled でも初期選択されるが、そのまま送信しても値は送られない |
Fx, IEと同じ | disabled な選択肢も選択可能だが、その場合は値は送られない |
最初の選択肢がdisabled でも初期選択され、そのまま送信すると値が送られる (いちど選択を外すと二度と選択できない) |
multiple なoption 要素にdisabled 属性 |
disabled な選択肢は無効となる |
Fx, IEと同じ | Fx, IEと同じ | Fx, IEと同じ | option 要素に設定した場合と同じ |
Fx, IEと同じ |
optgroup 要素にdisabled 属性 |
option 要素に設定した場合と同じ |
disabled な選択肢は無効とならず、値も送られる |
option 要素に設定した場合と同じ |
最初の選択肢がdisabled でも初期選択され、そのまま送信すると値が送られる (いちど選択を外すと二度と選択できない) |
option 要素に設定した場合と同じ |
option 要素に設定した場合と同じ (Operaと同じ) |
上記HTMLで何も変更せずボタンを押した時の送信データ | s1=1&s3=1 |
s1=1&s3=0 |
(なし) | s1=1&s3=0 |
(なし) | s1=0&s3=0 |
主な注目点をまとめてみます。
- FirefoxとIEの動作には、不自然な点は見当たらない
- Google Chromeは、
optgroup
要素に対するdisabled
属性に対応していない - iPhoneやiPadのSafariは、
disabled
な選択肢も選択できるが、その場合は値は送信されない - (表には含めていないが)IE7以前は、
option
要素とoptgroup
要素に対するdisabled
属性に対応していない。select
要素に設定した場合を除き、未設定時と同じ状態になる。
と、このようにブラウザによって表示や挙動がまちまちです。しかしながら、そもそも一部要素に対するdisabled
属性の指定が無視されるGoogle ChromeやIE7以前は別として、これらはブラウザの実装が貧弱なわけではなく、先に挙げたHTMLにも問題があります[1]。
option
要素のselected
属性
option
要素にselected
属性を設定すると、初期状態で選択済み状態になりますが、HTML4.01では次のような記述があります。
If no OPTION element has the selected attribute set, user agent behavior for choosing which option is initially selected is undefined.
(中略)
authors should ensure that each menu includes a default pre-selected OPTION.

すなわち、select
要素には必ず1つはselected
属性の付いたoption
要素がないといけないのです。なお、ラジオボタンも同じような規定があり、1つ
checked
属性を設定しなければなりません。
実際のブラウザの動作を見ると、checked
属性のないラジオボタンはいずれも選択されない状態となる一方、selected
属性のないプルダウンは一番目の選択肢が選択されるケースが多いので、たまたま一番目がデフォルト値な場合はselected
属性が書かれないケースが多い気がします。いずれにしても、プルダウンのoption
要素には必ずひとつselected
属性を付けるようにしましょう。SafariやOpera、Android標準ブラウザでは先に挙げたような問題がなくなります。
ただし、Google Chromeがoptgroup
要素のdisabled
属性に対応していなかったり、iPhoneやiPadのSafariでdisabled
な選択肢も選択できてしまう問題は解決しません。可能であればJavaScriptでDOMから除去してしまうのが良いと思います。
脚注
-
1.
とはいえiPhone, iPadの挙動はどう考えてもおかしいと思います。 ↩ 戻る