Skip to content

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 ベースで実装することがある。要素名を知っていれば的確に指示できる