fieldset + float
fieldset要素に対してdisplay: flex、grid、tableといった2カラムレイアウトを簡単に実装できるdisplay値を設定しても、意図したように2カラムにすることはできない。そのため、fieldset要素を使って2カラムレイアウトを実装しようとする場合、floatを使う必要がある。
floatを使った2カラムレイアウトは、flex、grid、tableのようにボックス内で上下中央配置ができず、隣り合うボックス同士の高さも揃わないため、実装できるレイアウトに制限が生じる可能性がある。
また、ブラウザ標準スタイルのlegend要素はfieldset要素の枠の上に重なるように表示させるため、ブラウザ独自の特殊なスタイルが適用されている。そのため、通常の要素と同じように配置をするためには個別に位置調整をする必要がある。
fieldset + display:contents + flexbox
display: flexやgridは、直下の子要素をアイテムとしてレイアウトコントロールするが、display: contentsが適用された要素は、CSSのレイアウトにおいて存在しないものとしてスキップされるようになるため、直下にfieldsetやlegendがあってもこのタグは存在しないものとみなしてレイアウトが適用できるようになる。
<div class="form__item">
<fieldset> <!-- <fieldset>は存在しないものとしてスキップされる -->
<div class="form__ttl">
<!-- <legend>は存在しないものとしてスキップされる -->
<legend>性別<span class="label-any">任意</span></legend>
</div>
<div class="form__body">
<ul class="radioList">
<li><label><input type="radio" name="gender" value="男"><span>男</span></label></li>
<li><label><input type="radio" name="gender" value="女"><span>女</span></label></li>
<li><label><input type="radio" name="gender" value="その他"><span>その他</span></label></li>
</ul>
</div>
</fieldset>
</div>
.form fieldset, .form legend {
display: contents; /* CSS上は要素として存在しないものとみなす */
}
.form__item {
display: flex; /* 対象がdiv要素のみとなるのでflex利用可 */
align-items: center; /* floatではできないコンテンツの上下中央揃え */
}
WAI-ARIA + flexbox
floatでは実装しづらいレイアウトであっても、どうしてもフォームグループの構造をスクリーンリーダーなどの支援技術でも適切に伝えたい、という場合は、divやtableなどでマークアップして必要なレイアウトを実装しつつ、スクリーンリーダーなどの支援技術に対してはWAI-ARIAという支援技術向けのアクセシビリティ仕様を使って別途フォームグループの関連付けをするのが良い。
ul要素でグループ化されている3つのラジオボタンに対して、「性別」というラベルが紐づけられているということがスクリーンリーダーに伝われば良いので、グループ見出しに該当する要素にid属性を付け、複数のフォームがグループ化されているul要素の部分にaria-labelledby属性でグループ見出しのid属性を指定することで、フォームグループとそのグループラベルを紐付けしておく。
この方法であればスクリーンリーダーに対する情報提供は担保できるので、実際のマークアップについては必ずしもfieldset+legendを使う必要はない。
<div class="form__item">
<div class="form__ttl" id="genderGroupLabel">性別<span class="label-any">任意</span></div>
<div class="form__body">
<ul class="radioList" aria-labelledby="genderGroupLabel">
<li><label><input type="radio" name="gender" value="男"><span>男</span></label></li>
<li><label><input type="radio" name="gender" value="女"><span>女</span></label></li>
<li><label><input type="radio" name="gender" value="その他"><span>その他</span></label></li>
</ul>
</div>
</div>
</div>