HTML5 で button
要素の中にフレージングコンテンツしか入れられなくなっていた
何を今さらって話なんですけど、お恥ずかしながらさっき気づいたので。
その昔、 HTML4 では button
要素 の中に p
要素や div
要素などを置くことが可能でした。DTDには以下のように定義されており、%flow;
とは %block; | %inline;
を指します。
<!ELEMENT BUTTON - - (%flow;)* -(A|%formctrl;|FORM|FIELDSET) -- push button -->
これはつまり、
<p><button><div>p の中の button の中に div</div></button></p>
や
<p><button><p>p の中の button の中に p</p></button></p>
が正当であることを意味します。
おそろしいことに、こんなマークアップもできたんですね。
<p><button>
<table border="">
<caption>p の中のbutton の中に table</caption>
<thead>
<tr>
<th scope="col">セル</th><th scope="col">セル</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">セル</th><td>セル</td>
</tr>
</tbody>
</table>
</button></p>
ですが、 HTML5 や HTML Living Standard ではbutton
要素のコンテンツモデルがPhrasing content, but there must be no interactive content descendant.
とされたため、上記のマークアップは invalid となります。
でも、現実問題として button
要素の中に div
や p
を入れたいこと、ありますよねえ……。
リンクアンカーに関しては、 a
要素の中に div
要素を入れられるようになったため、タッチデバイスを意識して div
要素を使うボックス枠ごとクリッカブルにするデザインが簡単にできるようになりましたが、同じようにボックス枠自体をダイアログやアコーディオンを表示するフックとなるボタンにすることはできなくなりました。もちろん、 div
要素が適切であるところすべて span
要素にして、 CSS で display: block
とかやれば、とりあえずマークアップとしては正当なものになりますが、うーんこのもやもや感。