Appearance
Day 5: 専用の HTML 要素で作れる UI — dialog, popover, details
今日のゴール
- モーダルダイアログ、折りたたみ、ポップオーバーに専用の HTML 要素があることを知る
- これらの HTML 要素がアクセシビリティやキーボード操作を自動で処理してくれることを知る
- 新しい HTML 機能を使うときの判断基準(Baseline)を知る
よく見る UI パーツには専用の HTML 要素がある
普段使っている Web サイトで、こんな UI を見たことがあるはずです:
- 確認画面やログインフォームが画面の上に重なって表示されるモーダルダイアログ
- FAQ ページなどの、クリックすると開閉する折りたたみ
- ボタンを押すとヘルプやメニューが浮き上がるポップオーバー
こうした UI には専用の HTML 要素が用意されています。専用要素を使うとキーボード操作やスクリーンリーダー対応が自動で付いてくるため、JavaScript でゼロから作るより少ないコードで、品質の高い UI が作れます。
AI にこうした UI を頼むと、専用要素を使わずに JavaScript ベースで返ってくることがあります。HTML の要素名を知っていれば、「<dialog> を使って」のように的確に指示できます。
新しい HTML 機能と Baseline
HTML には今も新しい要素や属性が追加されています。ただし、すべてのブラウザですぐに使えるとは限りません。
その判断基準になるのが Baseline です。Chrome・Safari・Firefox・Edge の対応状況をもとに、3 段階で分類されています。
| ステータス | 意味 |
|---|---|
| Limited availability | 一部のブラウザでしか使えない。本番投入には慎重に |
| Newly available | 主要ブラウザの最新版すべてで対応して 30 ヶ月未満。ただしブラウザを更新していないユーザーには動かない。たとえば Safari は OS ごとの更新が必要なため、リリースから数ヶ月経っても約 4 人に 1 人が旧バージョンを使っているというデータがある |
| Widely available | 主要ブラウザすべてで対応して 30 ヶ月以上。ほとんどのユーザーが更新済みと期待できる |
本番で使う機能は Widely available を目安にするのが安全です。Newly available の機能を使う場合は、未対応ブラウザ向けのフォールバック(代替表示)を用意しましょう。MDN の各ページや web.dev/baseline で確認できます。今日紹介する 3 つの機能はすべて Widely available です。
dialog — モーダルダイアログ
Baseline: Widely available
確認画面、ログインフォーム、設定パネルなど、画面の上に重なって表示され、閉じるまで背後を操作できなくする UI をモーダルダイアログと呼びます。
まずはデモを試してみてください。背景が暗くなり、Escape キーや「キャンセル」で閉じられます:
モーダルを JavaScript でゼロから作ろうとすると、考慮すべきことが多くなります:
- 背景を暗くするオーバーレイ
- 背後のスクロールを止める
- フォーカスをダイアログ内に閉じ込める(フォーカストラップ)
- Escape キーで閉じる
- スクリーンリーダーへの通知
<dialog> 要素の showModal() を使えば、これらがすべて自動で処理されます。
html
<button id="open-btn" type="button">ダイアログを開く</button>
<dialog id="my-dialog">
<h2>確認</h2>
<p>この操作を実行しますか?</p>
<div>
<button type="button" onclick="document.getElementById('my-dialog').close()">キャンセル</button>
<button type="button" onclick="document.getElementById('my-dialog').close()">実行する</button>
</div>
</dialog>
<script>
document.getElementById("open-btn").addEventListener("click", () => {
document.getElementById("my-dialog").showModal();
});
</script>showModal() で開き、close() で閉じます。これだけで以下がすべて自動的に提供されます。
| 機能 | 動作 |
|---|---|
| 背景のオーバーレイ | ::backdrop で CSS スタイルを適用できる |
| フォーカストラップ | Tab キーの移動がダイアログ内に閉じ込められる |
| Escape キーで閉じる | デフォルトで対応 |
| スクリーンリーダー | role="dialog" が自動付与される |
| 背後のスクロール防止 | モーダルが開いている間、背後はスクロールできない |
details / summary — 折りたたみ
Baseline: Widely available
FAQ ページなどでよく見る、クリックすると内容が展開されるアコーディオン UI です。
クリックして開閉してみてください:
Q. 返品はできますか?
商品到着後7日以内であれば、未使用品に限り返品を承ります。返品をご希望の場合は、カスタマーサポートまでご連絡ください。
Q. 送料はいくらですか?
全国一律550円です。5,000円以上のお買い上げで送料無料になります。
Q. 支払い方法は何がありますか?
クレジットカード、銀行振込、コンビニ払いに対応しています。
JavaScript は一切不要です。ブラウザがキーボード操作やスクリーンリーダー対応もすべて処理します。
html
<details>
<summary>Q. 返品はできますか?</summary>
<p>商品到着後7日以内であれば返品可能です。</p>
</details><details>が折りたたみ領域全体<summary>がクリック可能な見出しopen属性を付けると最初から展開された状態になる
name 属性で排他的アコーディオン
複数の <details> に同じ name 属性を付けると、1 つ開くと他が自動的に閉じる排他的なアコーディオンになります。JavaScript は不要です。
1 つ開くと、前に開いていたものが自動で閉じます:
Q. 返品はできますか?
商品到着後7日以内であれば返品可能です。
Q. 送料はいくらですか?
全国一律550円です。
Q. 支払い方法は?
クレジットカード、銀行振込、コンビニ払いに対応しています。
html
<details name="faq">
<summary>Q. 返品はできますか?</summary>
<p>商品到着後7日以内であれば返品可能です。</p>
</details>
<details name="faq">
<summary>Q. 送料はいくらですか?</summary>
<p>全国一律550円です。</p>
</details>同じ name="faq" を持つ <details> は、1 つを開くと他が自動的に閉じます。
popover — ポップオーバー
Baseline: Newly available(2024 年に主要ブラウザで対応)
ヘルプやメニューなど、ボタンを押すと浮き上がって表示される UI です。dialog と違い、背後の操作はブロックしません。
ボタンを押してみてください:
ここにヒントの内容が表示されます。外側をクリックするか Escape キーで閉じます。
popover 属性を付けた要素は最初は非表示で、popovertarget で紐付けたボタンをクリックすると表示されます。
html
<button popovertarget="help-popup" type="button">ヘルプ</button>
<div id="help-popup" popover>
<p>ここにヘルプの内容が表示されます。</p>
</div>| 機能 | 説明 |
|---|---|
| light dismiss | 外側をクリックすると自動的に閉じる |
| Escape キー | Escape キーでも閉じる |
| トップレイヤー | z-index を気にせず常に最前面に表示される |
| トグル動作 | ボタンを再度クリックすると閉じる |
popover の位置決め — CSS Anchor Positioning
popover だけだと、表示される場所を指定できません。ボタンの近くに出したいときは CSS Anchor Positioning(Baseline: Limited availability、Chrome・Firefox が対応済み。Safari も 2026 年中に対応予定)を組み合わせます。対応ブラウザでは上のデモでボタンの真下にツールチップが表示され、画面の端でスペースが足りないときは自動的に反対側に表示されます。
css
/* ボタンをアンカーとして登録 */
.trigger {
anchor-name: --my-anchor;
}
/* popover をアンカーの下に配置(スペースがなければ自動で上に) */
.tooltip {
position-anchor: --my-anchor;
inset: unset;
top: anchor(bottom);
left: anchor(center);
translate: -50% 0;
margin-top: 8px;
position-try-fallbacks: flip-block;
}popover で表示/非表示を、CSS Anchor Positioning で「どこに出すか」を、それぞれ指定する組み合わせです。
dialog と popover の使い分け
どちらも「浮き上がって表示される UI」ですが、用途が異なります。
| dialog(showModal) | popover | |
|---|---|---|
| 背後の操作 | ブロックする | ブロックしない |
| 閉じ方 | 明示的に閉じる操作が必要 | 外側クリックで閉じる |
| 用途 | 確認、ログイン、設定パネル | ツールチップ、メニュー、通知 |
「ユーザーに操作を求める」なら dialog、「補助的な情報を表示する」なら popover です。
まとめ
<dialog>:showModal()でモーダルダイアログが作れる。フォーカストラップ、Escape 対応、背景暗転が自動<details>/<summary>: JavaScript なしで折りたたみが作れる。name属性で排他制御も可能popover属性: ポップオーバーが作れる。外側クリックで閉じる、常に最前面に表示- 新しい HTML 機能を使うときは Baseline で対応状況を確認する
- AI はこれらを使わず JavaScript ベースで実装することがある。要素名を知っていれば的確に指示できる