HTML で <select> 要素を <hr> でセパレートできるようになった

HTML Living Standard の5月2日付けの更新で <select> 要素の子要素として <hr> を含めることができるようになりました。

<select> 要素の中をグループ化する方法としては、従来から <optgroup> 要素が存在しますが、これは label 属性による可視ラベルの設定が必須なため、ラベルなしの単なる区切りを示すことはできません。

<!-- `optgroup` 要素によるプルダウンのグループ化マークアップ例 -->
<label for="prefectures">都道府県</label>
<select name="prefectures" id="prefectures">
  <option>北海道</option>
  <optgroup label="東北地方">
    <option>青森県</option>
    <option>岩手県</option>
    <option>...</option>
  </optgroup>
  <optgroup label="関東地方">
    <option>茨城県</option>
    <option>栃木県</option>
    <option>...</option>
  </optgroup>
</select>

グループ化(区切り線の表示)は必要だが、ラベルを入れるのは冗長であるケースは、OS やアプリケーションの UI ではメニューバーやコンテキストメニューなどで一般的に見られるので、Web でもそのような表現が必要であることに異論は多くないでしょう。

Windows 10 + Firefox 114 のメニューバーの例

一方で、その実現方法は複数の手段が考えられます。

方法の一つとして、<optgroup> 要素の label 属性が現状必須であるのを任意に変更するというものがあります。これはセマンティックなグループ化のマークアップの面では良さそうですが、議論の中でも提案はあったものの、とくに話題が続かず、採用されませんでした。

もう一つは <select> 要素の子要素に <hr> 要素を許可するもの。今回の変更はこちらです。

<!-- `hr` 要素によりプルダウンを区切るマークアップ例 -->
<label for="editing">編集</label>
<select name="editing" id="editing">
  <option>元に戻す</option>
  <option>やり直し</option>
  <hr />
  <option>切り取り</option>
  <option>コピー</option>
  <option>貼り付け</option>
  <option>削除</option>
  <hr />
  <option>すべて選択</option>
  <hr />
  <option>ページを検索...</option>
</select>

実は一部のブラウザでは、従来からスクリプトによる DOM 操作で <option> 要素間に <hr> 要素を挿入し、区切りを表現することが可能でした。

しかし、これは Firefox など対応していないブラウザもあります。また、スマホブラウザは元々 <option> ごとに区切りを表示する見た目になっていたり(iOS Safari)、select > hr がまるでラベルのない <option> のように扱われたりする(Android Chrome)などの状況となっているため、ブラウザ側の対応を待たないとすぐには導入しづらい面もあります。

とはいえ、HTML 仕様に取り込まれたことで、今後はブラウザの対応が進むことも期待されます。

なお、注意点として、以下のようなものがあります。

  • プルダウンで <hr> 要素が許可されるのは <select> 要素の子要素の場合のみであり、例えば <optgroup> 要素内に配置することはできない(なぜ?(GitHub)
  • 連続した <hr> 要素は一つのセパレーターとしてレンダリングされる可能性がある(「15 Rendering」の select 要素の節(WHATWG)

また、プルダウンに <hr> 要素が使用できるのなら <ol>, <ul> などのリストでも許可できないかということで、Issue #9126(GitHub) が立っているので、こちらも動向を注視したいところです。

2023年6月6日追記macOS Safari 17 が対応するようです。👉News from WWDC23: WebKit Features in Safari 17 beta(webkit.org)