2023 年に 「HTML Living Standard」がマークアップにとってなぜ大切なのか? という記事を書きました。
あれから 2 年半、HTML Living Standard は進化を続けています。
改めて HTML Living Standard を読み直したら新しい機能が増えていたので紹介したいと思います。
本記事は 2026 年 6 月時点の HTML Standard を参照しています。ブラウザ実装状況は仕様によって幅があるので、実プロジェクトに投入する前に最新の対応状況をご確認ください。
HTML Living Standard の仕様書は定期的に見に行く方がいい
当然ですが、HTML Living Standard は更新し続けられています。
気付いたらこれまで JS や CSS を用いて表現していたものが HTML だけでできる ということが起こります。
例えば下記のようなことができるのを知っていますか?
<details name="faq">
<summary>質問 1</summary>
...
</details>
<details name="faq">
<summary>質問 2</summary>
...
</details>
<details> に name 属性を付けるだけで排他的アコーディオン(同時に 1 つしか開かない)が JS なしで実現できる、というのもその 1 つです。
2年前の自分が知らなかった、こうした「あれから増えた仕様」を紹介します。
今回題材にしたい振り返り
2023 年時点の記事では、当時 HTML Living Standard に新しく入っていた要素や属性を整理しました。
当時カバーしたもの(一部抜粋)
- 新規要素:
<hgroup>,<slot>,<search>,<menu> - Popover 関連: popover / popovertarget / popovertargetaction
- パフォーマンス: loading, fetchpriority, decoding
- a11y/入力: inert, enterkeyhint
実はこの 2 年半で、「JS で書くのが当たり前だった機能」が次々と HTML だけで完結するようになっていました…。
どんな新仕様が追加されたのか、見ていきます。
次に UI を実装するときに「これ HTML だけで書けるかも?」と立ち止まれるようになってもらえることを願ってこの記事を書きます!
あれから増えた 7 つの HTML 仕様
① 排他的アコーディオン <details name="...">
複数の <details> 要素に同じ name 属性を付けると、そのグループ内で同時に開けるのは 1 つだけ になります。
<section>
<details name="faq">
<summary>質問 1: 料金はいくらですか?</summary>
<p>月額 1,000 円です。</p>
</details>
<details name="faq">
<summary>質問 2: 解約はどうすればいいですか?</summary>
<p>マイページから手続きできます。</p>
</details>
</section>
いわゆる FAQ ページや設定画面でおなじみの「1 つ開いたら他は閉じる」UI が、これまで JS なしには作れませんでした。
これからは name 属性 1 つで実現できます。
HTML 仕様の用語では「exclusive accordion」と呼ばれています。name 属性を共有する <details> 群が排他グループになります。
②ダイアログの閉じ方を制御する <dialog closedby="..."> と dialog.requestClose()
<dialog> 要素は便利ですが、「ユーザーが Esc キーや背景クリックで勝手に閉じられると困る」ケースもあります。
新しく追加された closedby 属性で、閉じる手段を宣言的に制御できるようになりました。
<!-- 背景クリックでも Esc でも閉じる -->
<dialog closedby="any">...</dialog>
<!-- Esc キー(close request)でのみ閉じる -->
<dialog closedby="closerequest">...</dialog>
<!-- 自動では閉じない(明示的に dialog.close() を呼ぶ必要あり) -->
<dialog closedby="none">...</dialog>
加えて、dialog.requestClose() メソッドも追加されました。
これは cancel イベントを発火させてから閉じる メソッドで、フォーム入力中など「閉じる前に確認したい」場面で使えます。
dialog.addEventListener("cancel", (event) => {
if (hasUnsavedChanges) {
event.preventDefault(); // ← キャンセル可能
}
});
closeButton.addEventListener("click", () => {
dialog.requestClose(); // ← cancel イベント経由で閉じる
});
close() だと問答無用で閉じてしまうのに対し、requestClose() は「閉じてもいい?」をユーザーや実装に確認できる、というイメージです。
③ ボタンから宣言的に UI を操作する command / commandfor
<button> に command と commandfor 属性を付けるだけで、指定した要素を JS なしで開閉できるようになりました。
<button command="show-popover" commandfor="my-popover">ポップオーバーを開く</button>
<div id="my-popover" popover>
<p>JS なしで開閉できます</p>
</div>
command 属性には以下のような値が指定できます。
-
show-popover,hide-popover,toggle-popover— popover の制御 -
show-modal,close,request-close— dialog の制御
特に dialog の request-close は、先ほど紹介した dialog.requestClose() を ボタン側から宣言的に呼び出せる手段です。
<button command="request-close" commandfor="my-dialog">閉じる</button>
従来の popovertarget 属性は popover にしか使えませんでしたが、command / commandfor は dialog にも対応 していて、より汎用的に使えます。
④ writingsuggestions グローバル属性テキスト入力補完の制御
ブラウザのテキスト入力では、時折入力中に補完候補(writing suggestions)が表示されます。
これを 要素単位で無効化 できるのが writingsuggestions 属性です。
<!-- パスワード強度を表示する入力欄など、補完を出したくない場面 -->
<input type="text" writingsuggestions="false" />
<!-- 補完を明示的に有効化(デフォルト) -->
<textarea writingsuggestions="true">...</textarea>
「補完で意図しない文字に書き換わって困る」というケース(コード入力、ID 入力など)で重宝します。
これまでは autocomplete="off" などで間接的に抑えるしかありませんでしたが、補完そのものを制御する専用属性ができた、というわけです。
⑤ headingoffset / headingreset グローバル属性 見出しレベルのオフセット
部品化されたコンポーネント(カード、サイドバー、モーダルなど)をページに埋め込むとき、そのコンポーネント内の見出しを何レベルにすべきか は文脈によって変わります。
これまでは「常に <h2> で書く」「親から prop で受け取る」など、手作業で調整するしかありませんでした。
<article>
<h1>記事タイトル</h1>
<!-- このセクション内の見出しを 1 レベルずらす -->
<section headingoffset="1">
<h1>本来は h2 として扱われる</h1>
<section>
<h1>本来は h3 として扱われる</h1>
</section>
</section>
</article>
headingoffset を指定すると、その配下の見出しは指定されたレベル分だけシフトされて解釈されます。
コンポーネント側は常に <h1> で書いておけば、配置先の文脈に応じてレベルが自動調整されます。
この機能は仕様には入っていますが、執筆時点(2026 年 6 月)でブラウザ実装はまだ広がっていません。
プロダクション投入は caniuse で対応状況を確認してから判断してください。
気にしなくても良くなったという点では、見出しレベルが間違えるリスクは減りましたが、人が見た時に混乱しそうだというのが正直な感想です…。
⑥ <selectedcontent> Customizable Select の中核要素
長年フロントエンドの課題だった「<select>(プルダウン)のデザインを CSS で自由にカスタマイズしたい」という要望に応える、Customizable Select が仕様化されました。
その中で登場した新しい要素が <selectedcontent> です。
<select> の中で <selectedcontent> を使うと、現在選択されているオプションの中身(テキストだけでなく国旗や画像も含む)を、選択ボタン上に自由なスタイルで表示できます。
<select>
<button>
<selectedcontent></selectedcontent>
</button>
<option><img src="/jp.png" alt=""> 日本</option>
<option><img src="/us.png" alt=""> アメリカ</option>
</select>
CSS 側で appearance: base-select を指定することで、ブラウザのデフォルト UI から離れ、完全にカスタムの見た目の <select> を構築できます。
仕様提案の初期段階では <selectedoption> という名前でしたが、議論を経て <selectedcontent> にリネームされました。古い記事や提案ドキュメントを参照する際は注意してください。
⑦ <details> の開閉アニメーション CSS との合わせ技
これは厳密には「HTML 仕様の新規追加」というより、CSS 側の進化と組み合わせた新しい書き方です。
これまで <details> の開閉は瞬間的で、アニメーションさせるには中身を <div> で包んで高さを JS で計算する、といった工夫が必要でした。
CSS の interpolate-size: allow-keywords と transition を組み合わせることで、JS なしでスムーズな開閉アニメーションが実現できます。
:root {
interpolate-size: allow-keywords;
}
details::details-content {
block-size: 0;
overflow: hidden;
transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
details[open]::details-content {
block-size: auto;
}
auto という抽象的な値も補間できるようになったことで、<details> の中身のような「開いてみないとサイズが分からない」要素もアニメーションできるようになりました。
こちらも CSS 側の仕様なのでブラウザ対応に幅があります。@supports (interpolate-size: allow-keywords) で対応ブラウザにだけ適用するのが安全です。
なぜこれらが嬉しいのか
7 つの新機能を、Before / After で並べてみます。
| やりたいこと | Before(JS や工夫が必要) | After(HTML / CSS だけで) |
|---|---|---|
| 排他的アコーディオン | JS で開閉状態を管理 | <details name="..."> |
| ダイアログの閉じ方制御 | ライブラリで実装 or 自前 JS |
closedby 属性 |
| 閉じる前の確認 |
close() 前に手動で confirm()
|
requestClose() + cancel イベント |
| ボタンから dialog / popover を操作 |
popovertarget で popover のみ可 |
command / commandfor で dialog にも対応 |
| テキスト補完の抑止 |
autocomplete="off" で代用 |
writingsuggestions="false" |
| 見出しレベルの動的調整 | コンポーネント間で prop 受け渡し |
headingoffset 属性 |
<select> のスタイルカスタム |
<div> で自作 or ライブラリ |
<selectedcontent> + appearance: base-select
|
<details> 開閉アニメ |
中身を包んで JS で高さ計算 |
interpolate-size: allow-keywords + transition |
**「これまで JS でやっていたことが、HTML 単独でできる」**方向への進化が顕著です。
JS が要らなくなれば、それだけバンドルサイズが減り、初期表示が速くなり、a11y も自動的に良くなります。
HTML 本体ではないが注目したい新しい仕様
ここまで紹介してきたのは HTML Living Standard 本体に正式収録された仕様 です。
加えて、WICG(Web Incubator Community Group)で 先行して仕様策定が進んでいる注目要素 にも触れておきます。
HTML 本体に取り込まれる可能性のあるものなので、ウォッチしておいて損はありません。
<fencedframe> — プライバシー保護を極めた埋め込み
<iframe> に似ていますが、親ページと埋め込み先フレームの間で通信やデータの共有を厳密に制限した新しい埋め込み要素です。
サードパーティ Cookie 廃止(Privacy Sandbox)の流れで提案され、主に広告の安全な埋め込みなどで <iframe> を置き換える目的で実装が進んでいます。
<fencedframe src="https://ads.example.com/banner"></fencedframe>
Chrome を中心に実装が進められており、Firefox / Safari は未実装です。
WICG 仕様であり、WHATWG HTML 本体には未収録です。仕様も実装も流動的なので、プロダクション利用は慎重に判断してください。
<permission> 権限ダイアログを宣言的に呼び出す
カメラ、マイク、位置情報などの ブラウザ権限の許可プロンプト を、HTML タグとして宣言的に呼び出せる新しい要素です。
これまで JS の navigator.permissions などを叩いて呼び出していたものを、HTML 側で完結させます。
<permission type="camera">カメラを使う</permission>
ブラウザ側で UI を統一することで、「ページを開いた瞬間に勝手に権限ダイアログを出すスパム行動」をシステムレベルで防ぐ狙いもあります。
こちらも WICG 仕様で、Chrome の Origin Trial 段階です。ブラウザ実装はまだ広がっていません。
HTML Living Standard は「定期的に確認」する
HTML Living Standard を追いかける習慣がないと、簡単に遅れる ということです。
リリースノートがないからこそ、Living Standard は 自分で能動的に見に行かないと更新に気付けません。
仕様を追うときは、一度問い直してみてください。
- いま自分が「JS でやっている処理」は、本当に JS が必要か
- それとも「2 年前には無かった HTML 属性で代替できる」か
「JS でやれること」と「JS でやるべきこと」は別 という視点を、HTML 仕様の進化が改めて教えてくれます。
定期的に HTML Living Standard を読み直す時間を作ることで実装コストを下げ、最新の仕様でマークアップし続けられるコツです。
忙しい人のためのまとめ
-
<details name>で排他的アコーディオンが JS なしで作れる -
<dialog closedby>+requestClose()でダイアログの閉じ方を宣言的に制御できる -
command/commandforで popover や dialog をボタンから宣言的に操作できる -
writingsuggestionsでテキスト補完を要素単位で制御できる -
headingoffsetでコンポーネントの見出しレベルを文脈に応じて自動調整できる -
<selectedcontent>で<select>のデザインを完全カスタマイズできる(Customizable Select) -
interpolate-sizeと組み合わせて<details>の開閉をアニメーションできる - WHATWG 本体外だが
<fencedframe><permission>も WICG で動いている