【HTML】古くて新しい menu 要素をもう一度見つめなおす

HTML の menu 要素って使ったことありますか?恐らくほとんどの人は使ったことないのではないでしょうか。実は、menu 要素は誕生してから波乱万丈な人生を歩んでおり、menu 要素を使ってよいのかすら良くわからない存在になっています。今回は、その menu 要素の歴史と今を解説します。これであなたは menu 要素を使いたくなるでしょう。

menu 要素の誕生

menu 要素は HTML が誕生したときにはすでに存在しており、ul 属性と同じリストを表す要素でした。

<menu>
  <li>項目1</li>
  <li>項目2</li>
  <li>項目3</li>
</menu>

このように、li 要素を使ってリストの項目をマークアップしました。基本的に ul 要素と同じです。そして、当時のブラウザーは menu 要素も li 要素も同じようにレンダリングしていました。

その後、HTML 2.0HTML 3.2 でも廃止されることなく存続し続けました。しかし、筆者が知る限り、これほど使われなかった要素は他にないんじゃないかと思うくらい、存在感がなかった要素です(あくまでも筆者の感想に過ぎません)。

HTML 4 で menu 要素が廃止

よほど人気がなかったせいか、ついに HTML 4 では menu 要素は廃止予定(deprecated)になりました。そして、代わりに ul 要素を利用することが推奨されました。

実は、ブラウザーは下位互換性を保つために、今でも menu 要素を認識します。そして、ul 要素と全く同じようにリストとしてレンダリングします。同じものがたくさんあっても仕方がない、ということで、マイナーだった menu 要素が廃止対象になったのでしょう。

実は、menu 要素の兄弟とも言える dir 要素というのもありました。dir 要素も ul 要素や menu 要素と同じく、リストとしてレンダリングされます。当然、この dir 要素も廃止対象となりました。

HTML5 誕生時に新たな menu 要素として復活

その後、HTML5 の策定が始まると menu 要素が復活しました。しかし、その用途は大きく変わりました。W3C で勧告に至る前の HTML5 仕様では、menu 要素はコンテキストメニュー、ツールバー、コマンドリストのいずれかになりました。いちおう、これらもリストと考えられなくはないのですが、用途がかなり限定されたと言えます。

それぞれの用途は type 属性によって区別され、その用途に応じて menu 要素の中に入れるコンテンツが決められていました。中に入れる要素が li 要素とは限らない点がポイントです。

以下は、当時の HTML5 仕様に書かれていたツールバーのマークアップ例です。

<menu type="toolbar">
 <li>
  <menu label="File">
   <button type="button" onclick="fnew()">New...</button>
   <button type="button" onclick="fopen()">Open...</button>
   <button type="button" onclick="fsave()">Save</button>
   <button type="button" onclick="fsaveas()">Save as...</button>
  </menu>
 </li>
 <li>
  <menu label="Edit">
   <button type="button" onclick="ecopy()">Copy</button>
   <button type="button" onclick="ecut()">Cut</button>
   <button type="button" onclick="epaste()">Paste</button>
  </menu>
 </li>
 <li>
  <menu label="Help">
   <li><a href="help.html">Help</a></li>
   <li><a href="about.html">About</a></li>
  </menu>
 </li>
</menu>
menu 要素によるツールバーのレンダリング例

以下は、コンテキストメニューの場合のマークアップ例です。

<form name="npc">
 <label>Character name: <input name=char type=text contextmenu=namemenu required></label>
 <menu type=context id=namemenu>
  <command label="Pick random name" onclick="document.forms.npc.elements.char.value = getRandomName()">
  <command label="Prefill other fields based on name" onclick="prefillFields(document.forms.npc.elements.char.value)">
 </menu>
</form>

いろんな機能を詰め込みすぎたせいか、なんだか良くわからない要素になってしまった印象を受けます。

HTML5 完成(勧告)時には廃止に

前述のマークアップ例を見てどのように感じましたでしょうか。ややこしくないですか?当然ながら、menu 要素を実装するブラウザーベンダーも現れませんでした。そして、W3C HTML5 仕様が勧告になった際には menu 要素は削除されてしまいました。

W3C では 2 つ以上のブラウザーが実装しないと、その仕様は勧告になれないというルールがありました。そのため、menu 要素を仕様から削除して HTML5 を勧告にしたという経緯があります。

HTML 5.1 で機能を限定して再復活

HTML5 の勧告では除外されてしまった menu 要素ですが、完全に廃止と決まったわけではありませんでした。その後、W3C で HTML5 はバージョンアップして HTML 5.1 が誕生します。ここで menu 要素が再復活しました。

以前の HTML5 の menu 要素は機能を盛り込みすぎて良くわからない要素になってましたが、HTML 5.1 の menu 要素はシンプルです。今度の menu 要素はコンテキストメニュー専用の要素として生まれ変わったのです。 コンテキストメニューとは、マウスで右クリックすると表示されるメニューリストのことです。

次のマークアップは、HTML 5.1 仕様に記載されたコンテキストメニューのマークアップ例です。

<img src="cats.jpeg" alt="Cats" contextmenu=catsmenu>
<menu type="context" id="catsmenu">
  <menuitem label="Pet the kittens" onclick="kittens.pet()">
  <menuitem label="Cuddle with the kittens" onclick="kittens.cuddle()">
  <menu label="Feed the kittens">
    <menuitem label="Fish" onclick="kittens.feed(fish)">
    <menuitem label="Chicken" onclick="kittens.feed(chicken)">
  </menu>
</menu>

このマークアップは、次のようにレンダリングされることが期待されました。

menu 要素によるコンテキストメニューのレンダリング例

コンテキストメニュー内の各項目のために、新たに menuitem 要素が作られました。サンプルのマークアップを見ても分かりやすくなったと感じますよね。

実は、この menu 要素を Firefox が実装したんです。当時は日本国内のウェブサイトでも menu 要素と menuitem 要素を使って作られたコンテキストメニューを見かけました。

HTML 5.2 でまたもや廃止に

次に W3C で HTML 5.2 が誕生しましたが、またもや menu 要素が削除されてしまいました。結局のところ、複雑な仕様だった menu 要素を実装するブラウザーが 2 つ以上現れなかったため、W3C では menu 要素は勧告になれなかったのでした。

WHATWG HTML 仕様でまたまた新たな menu 要素として復活

W3C が HTML5 仕様の策定を終了した現在、HTML の仕様といえば WHATWG HTML 仕様のことを指しますが、現時点の WHATWG HTML 仕様には menu 要素が規定されています。しかし、もはやコンテキストメニューではありません。 ツールバーになったのです。

仕様には次のように書かれています(日本語訳は筆者)。

The menu element represents a toolbar consisting of its contents, in the form of an unordered list of items (represented by li elements), each of which represents a command that the user can perform or activate.

menu 要素はツールバーを表します。そのコンテンツは項目の非順序リスト(li 要素で表されます)という形となり、それぞれの項目はユーザーが実行またはアクティベートすることができるコマンドを表します。

4.4.7 The menu element : WHATWG HTML

なんだか難しそうに書かれていますが、ようは、menu 要素は単に ul 要素の用途限定版に過ぎないということです。仕様にもそう書かれています(日本語訳は筆者)。

The menu element is simply a semantic alternative to ul to express an unordered list of commands (a “toolbar”).

menu 要素は、意味的には、コマンドの非順序リスト(ツールバー)を表現するための ul の代替に過ぎません。

以前のコンテキストメニューだった menu 要素のように、機能面でブラウザーが何かしてくれるわけではなくなりました。ul 要素と同じく、単なるリストです。

WHATWG HTML 仕様には、次のようなマークアップ例が記載されています。

<menu>
 <li><button onclick="copy()"><img src="copy.svg" alt="Copy"></button></li>
 <li><button onclick="cut()"><img src="cut.svg" alt="Cut"></button></li>
 <li><button onclick="paste()"><img src="paste.svg" alt="Paste"></button></li>
</menu>

近年はウェブアプリケーションも増え、ツールバーを HTML、CSS で表現することも増えてきました。また、Electron をはじめとした、HTML、CSS、JavaScript を使ってデスクトップアプリを作るようなツールが登場しています。そういったケースで menu 要素は重宝するでしょう。

まとめ

筆者は長年 HTML 仕様の歴史を眺めてきましたが、menu 要素ほど廃止と復活を繰り返す要素は見たことがありません。また、復活のたびに用途が変わるのも珍しいです。そのせいか、menu 要素を古い情報のまま誤解している人もいるのではないでしょうか。

現在の menu 要素はツールバーを意味するリストです。もちろん、ul 要素でツールバーをマークアップしても問題はありません。しかし、せっかく特定の用途向けに要素が別に設けられているわけですから、積極的に使っていきたいですね。かつての menu 要素のように複雑すぎることはなく、簡単に使えます。

今後は menu 要素が廃止になることはありません、と断言したいところですが、過去を振り返ると信じられないかもしれませんね。もちろん筆者も責任は持てませんので、自己責任で使ってくださいね。

今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。

Share