HTML

In HTML, the <optgroup> element is used to categorize multiple <option> elements within a <select> and display them in an organized manner with a label.

optgroup 要素

<optgroup>とは?

<optgroup>要素は、HTMLのフォーム要素である<select>タグの中で利用される要素のひとつです。主に複数の<option>をグルーピングし、オプション項目をカテゴリ分けして表示するために使用します。ユーザーに対しては、まとまりのある選択肢として視覚的または構造的にわかりやすくなるメリットがあります。

たとえば、大量の選択肢があるプルダウンメニューで、ジャンルごとにグループを分けるときなどに役立ちます。自動車メーカーの選択リストや、都道府県を地域ごとに分けるようなケースを想像すると分かりやすいでしょう。

<select>と<option>との関係

そもそも<select>要素はプルダウンメニューやリストボックスを作るために使われます。その中で、

という位置付けになっています。<option>は単独でも問題なく動作しますが、選択肢が多い場合やカテゴリごとにまとめたい場合に<optgroup>を使用すると、可読性やユーザビリティの向上を図ることができます。

基本的な構文と使い方

<optgroup>は、以下のように<select>内で利用します。必須の属性としては、グループ名を示すlabel属性が存在します。

HTML

<select name="example">
	<optgroup label="フルーツ">
		<option value="apple">りんご</option>
		<option value="banana">バナナ</option>
		<option value="orange">オレンジ</option>
	</optgroup>
	<optgroup label="野菜">
		<option value="carrot">にんじん</option>
		<option value="potato">じゃがいも</option>
		<option value="onion">たまねぎ</option>
	</optgroup>
</select>

ブラウザ上では、「フルーツ」「野菜」という見出しの下に選択肢が並ぶ形で表示されます。ユーザーがメニューを開くとグループごとの区切りやラベルが視覚的にわかりやすく見えるようになります。

<optgroup>が持つ属性

label属性

概要
グループ名を指定する属性で、必須です。ブラウザがグループの見出しとして表示してくれます。
注意
label属性が無い場合、意味的には正しくありません。HTMLのバリデーションでもエラーになりますので、必ず付与しましょう。

disabled属性

概要
この属性を付与すると、グループ全体が無効になり、対応する<option>も選択できなくなります。
使いどころ
ユーザーが選べないカテゴリを一時的に無効化したい場合など。システムの状態によっては特定のグループを無効化するなどの使い方ができます。
注意
disabledを付与した<optgroup>の中にあるすべての<option>は自動的に選択不可になります。また、ブラウザによってはグレーアウトして表示されます。

使用例:カテゴリ分けされたプルダウンメニュー

地域別の都道府県リスト

HTML

<select name="prefecture">
	<optgroup label="北海道・東北地方">
		<option value="hokkaido">北海道</option>
		<option value="aomori">青森県</option>
		<option value="iwate">岩手県</option>
		<!-- 以下略 -->
	</optgroup>
	<optgroup label="関東地方">
		<option value="tokyo">東京都</option>
		<option value="kanagawa">神奈川県</option>
		<option value="chiba">千葉県</option>
		<!-- 以下略 -->
	</optgroup>
	<!-- 他の地方も同様に -->
</select>

このように日本の都道府県を地方ごとにグループ化すると、ユーザーが素早く目的の選択肢を見つけやすくなるメリットがあります。

検索フォームでのカテゴリー選択

HTML

<select name="category">
	<optgroup label="本・書籍">
		<option value="novel">小説</option>
		<option value="comic">漫画</option>
		<option value="magazine">雑誌</option>
	</optgroup>
	<optgroup label="家電">
		<option value="tv">テレビ</option>
		<option value="pc">パソコン</option>
		<option value="camera">カメラ</option>
	</optgroup>
</select>

商品検索フォームなどでカテゴリをまとめると、ユーザーにとって論理的な分類を認識しやすくなります。

アクセシビリティとベストプラクティス

スクリーンリーダーとの連携

適切なラベルの命名

無理にグループ化しない

スタイリングとデザイン上の注意点

ブラウザの標準表示

<optgroup>はブラウザによって表示が若干異なりますが、ほとんどの場合太字やインデントがつけられ、グループ名が目立つようにレンダリングされます。ここではブラウザ依存のスタイルが適用されるため、細かい調整は難しい面があります。

CSSでの制御

コンポーネント化

応用テクニック・上級者向けポイント

<optgroup>のネスト(推奨されない方法)

厳密にはHTML仕様としては**<optgroup>を入れ子にすることは推奨されていません。一部ブラウザでは無視されたり、正しく表示されないケースがあります。複雑な階層表示が必要な場合は、<optgroup>を重ねるよりUIライブラリを使った別の階層構造**(たとえばドロップダウンリストを複数段階に分けるなど)を検討しましょう。

動的生成

JavaScript

const selectEl = document.getElementById("mySelect");

const groupEl = document.createElement("optgroup");
groupEl.label = "新しいカテゴリ";

const optionEl = document.createElement("option");
optionEl.value = "newItem";
optionEl.textContent = "新規アイテム";

groupEl.appendChild(optionEl);
selectEl.appendChild(groupEl);

ユーザビリティ向上のための工夫

よくある質問(FAQ)

  1. Q: label属性を省略したらどうなりますか?
    A: label属性は必須なので、省略するとHTMLのバリデーションエラーになります。意味論的にも正しくないので、必ず指定しましょう。
  2. Q: <optgroup>を無効化したい時はどうすればいい?
    A: disabled属性を使います。付与すると、その中の<option>も含めて選択不可になります。
  3. Q: <optgroup>をネスト(入れ子)にして階層構造を作れますか?
    A: 仕様上は一部ブラウザで動く場合がありますが、推奨されていません。整合性が取れない場合や、うまくレンダリングされない場合があるので避けましょう。
  4. Q: カスタムデザインを当てようとしてもスタイルが効かない箇所があります…
    A: 標準のプルダウンメニューはブラウザがネイティブコントロールとして表示します。CSSでの制御範囲は限定的です。大幅に変更したい場合はJavaScriptのUIコンポーネントを使用するのが一般的です。

まとめ

<optgroup>は、<select>要素の中で選択肢をカテゴリーごとにグループ化するための便利な要素です。

基本的な使い方
label属性によってグループ名を指定し、関連する<option>をまとめる。
利点
大量の選択肢を分かりやすく整理でき、ユーザーの操作性やアクセシビリティが向上する。
注意点
不要なまでの細かいカテゴリ分けは逆に操作を煩雑にするので、適切な粒度でグループ化する。ネストは非推奨。
アクセシビリティ
スクリーンリーダーが正しく読み上げるためにも、labelを使ってわかりやすい名称を付ける。

初学者の方は、まずは<select> + <option>の基礎を抑えつつ、必要なシチュエーションで<optgroup>を導入してみてください。中級者・上級者の方は、より複雑なUIが必要な場合にはJavaScriptライブラリを活用するなどしつつ、ユーザーが快適に利用できるインターフェースを設計してみると良いでしょう。