JavaScript不要。Popover APIを使ってHTMLのみでポップオーバーUIを実装



様々なWebブラウザでPopover API(ポップオーバー API)がサポートされ、これまではJavaScriptを使って実装していた、ポップアップやオーバーレイと呼ばれるポップオーバーUIを、HTMLのみで実装することができるようになりました。

ここでは、popover属性やpopovertarget属性を使ったポップオーバーUIを実装する方法についてご紹介します。

サポートされているWebブラウザは以下のリンクより確認できます。

Can I use (popover)
https://caniuse.com/?search=popover

2023年10月現在は、Google ChromeやMicrosoft Edge、Safari等、ある程度の主要ブラウザはサポートされています。追ってFirefoxもサポートされるでしょう。

非表示状態のポップオーバーコンテンツは、display:noneが適用されます。
気になります、display:noneによるSEOへの影響については後述します。

Popover APIの使用


Popover APIを使用することで、他のページコンテンツの上にポップオーバーコンテンツを表示することができます。
APIに関連する属性を設定することで、HTMLのみでポップオーバーUIが実装できます。

以下、Popover APIで用意されている設定です。

popover
HTML要素をポップオーバー要素にします。
ポップオーバー状態の値: “auto”、”manual”(デフォルトはauto)
popovertarget
buttonまたはinput要素をポップオーバー制御ボタンにします。
popover属性を設定したポップオーバー要素のIDを取ります。
popovertargetaction
制御ボタンで制御しているポップオーバー要素に対して行う動作を指定します。
動作を指定する値: “hide”、”show”、”toggle”


ポップオーバーコンテンツは表示状態では最上位レイヤーに配置され、z-indexの値に影響を受けることなく1番上に表示されます。
他の要素(レイヤー)との重なり順序を気にする必要はありません。

ここからはサンプルコードで見ていきます。

HTML構造は、ポップオーバーとする要素と、それを操作するボタンを用意します。

HTML

<button popovertarget="popover">Popover</button>
<div popover id="popover">
  <p>Hello, world!</p>
</div>



ポップオーバーとポップオーバーを操作する要素(ボタン)を関連付けるために、ポップオーバー要素とボタンをidで紐づけます。
(「popovertarget=”popover”」「id=”popover”」)

CSSでは、popover属性とpopovertarget属性の要素にスタイルを適用させています。
デフォルトのスタイルに余白を調整しているくらいです。

CSS

body {
  background-color: #e8e6fd;
  padding: 2rem;
}

[popover] {
  max-width: calc(100% - 20px);
  padding: 1.25rem;
}

[popovertarget] {
  margin: 0 0 .5rem;
}



実装結果を確認してみます。
popovertarget属性を設定したボタンをクリックすると、画面中央にポップオーバーが表示されます。

Popover APIを使ったポップオーバーUIの実装



ポップオーバーを非表示(閉じる)とする場合は、ポップオーバーの外側をクリックする、またはIDで紐づけたpopovertarget属性を設定したボタンをクリックします。
他、PCであればEscキーを押しても閉じることができます。

Closeボタンを設置する


表示を閉じる方法としてわかりやすく、Closeボタンを設置するのもいいでしょう。
popover属性の要素内に、button要素でCloseボタンを作っていきます。

HTML

<button popovertarget="popover1">Popover1</button>
<div popover="manual" id="popover1">
  <p>Hello, world!</p>
  <button popovertarget="popover1" popovertargetaction="hide" class="close-btn">
    <span>Close</span>
  </button>
</div>



popovertarget属性は、制御するポップオーバー要素のIDを指定します。
popover属性の値を「manual」としますと、popovertarget属性が設定されているボタンのみ表示の制御が可能となります。
popovertargetaction属性は「hide」とします。
「show」とするとpopover属性の要素と同様に表示の制御操作の対象とならず、Closeボタンの意味がなくなります。
ほか、装飾用にCSSクラス「close-btn」を付与しています。

CSSでは、Closeボタンのスタイルのみ追加しています。
お好みのボタンのデザインに変えていただいてもOKです。

CSS

body {
  background-color: #e8e6fd;
  padding: 2rem;
}

[popover] {
  max-width: calc(100% - 20px);
  padding: 1.25rem;
}

[popovertarget] {
  margin: 0 0 .5rem;
}

.close-btn {
  display: block;
  margin: 1.5rem auto 0;
}
ポップオーバーコンテンツにCloseボタンを設置する



popover属性の値を「manual」にするとボタンのみの表示制御となりますので、PCのクリック操作はもちろん、モバイル端末でもタップしやすいデザインにするといいでしょう。

スタイル設定を支援するCSS機能


Popover APIに対応したスタイル設定を支援するCSS機能があります。
ポップオーバー要素のデフォルトのスタイルを調整する際に利用できます。

:popover-open
popover-open擬似クラスは、ポップオーバー要素が表示状態にあるときを表します。ポップオーバー要素が表示されているときのスタイルを適用させることができます。

::backdrop
擬似要素::backdropは、ポップオーバー要素の後ろに配置される全画面要素で、ポップオーバーの背後にある要素にスタイルを適用させることができます。



擬似クラスや擬似要素を使ってスタイルを調整してみます。

HTML

<button popovertarget="popover2">Popover2</button>
<div popover="manual" id="popover2">
  <p>:popover-open記事クラスで表示時のスタイルを適用<br>::backdrop擬似要素で背景にスタイルを適用</p>
  <button popovertarget="popover2" popovertargetaction="hide" class="close-btn">
    <span>Close</span>
  </button>
</div>

CSS

body {
  background-color: #e8e6fd;
  padding: 2rem;
}

[popover] {
  max-width: calc(100% - 20px);
  padding: 1.25rem;
}

[popovertarget] {
  margin: 0 0 .5rem;
}

.close-btn {
  display: block;
  margin: 1.5rem auto 0;
}

/* :popover-open擬似クラスで表示時のスタイルを適用 */
#popover2:popover-open  {
  border: none;
  box-shadow: 0px 0px 8px #555;
}

/* 擬似要素::backdropで背景にスタイルを適用 */
#popover2::backdrop {
  background-color: #000;
  opacity: .5;
}


ボーダースタイルからシャドウスタイルに変更してみました。
また、背景を少し暗くするよう背景色と背景色に対する透過度をしていしています。

ポップオーバー要素のスタイルを調整する



ちなみに、背景をぼかすような表現をする場合は、backdrop-filterプロパティでblur効果を適用させます。

CSS(背景をぼかす)

#popover2::backdrop {
  backdrop-filter: blur(3px);
}

ポップオーバーにアニメーションを実装する


display:noneからdisplay:blockでのフェード効果は実装できませんので、@keyframesとopacityプロパティを使ってフェード効果を実装します。
@keyframesでフェード効果を定義しておき、popover属性が指定してある要素が表示される時に、animationプロパティでアニメーションを適応させて表示します。

これまでのサンプルコードに、以下のCSSコードを追加します。

CSS

[popover]:popover-open {
  animation: appear .8s ease;
}

@keyframes appear {
  0%{
    opacity: 0;
  }
  100%{
    opacity: 1;
  }
}


フェードイン効果はCSSのみで実装できますが、フェードアウトの効果はpopover属性の仕様でdisplay:noneが適応されますので、JavaScriptを使う必要がでてきます。

ポップオーバーの表示位置の調整


実装したポップオーバーは画面中央に表示されますが、これはpopover属性の既存のスタイル設定となります。
以下のスタイル設定が適応されています。

[popover] {
  position: fixed;
  inset: 0;
  width: fit-content;
  height: fit-content;
  margin: auto;
  border: solid;
  padding: 0.25em;
  overflow: auto;
  color: CanvasText;
  background-color: Canvas;
}


ポップオーバーの表示位置の調整する場合は、popover属性「[popover]」やpopover属性が設定された要素の表示時「[popover]:popover-open」に調整するスタイルを指定します。

以下のサンプルコードは、画面下中央にポジション調整しています。

CSS

[popover]:popover-open {
  top: auto;
  bottom: 1rem;
  margin: 0 auto;
}

ポップオーバーの幅の調整


Popover APIで実装するポップオーバーは、コンテンツ量によってはうまく改行を入れないかぎり画面幅いっぱいに表示されます。スマートフォンやタブレット端末では画面幅に対して左右に10pxほど余白をとるとコンテンツが見やすいので、calc関数を使って幅100%から20px引いた数値を最大幅とするといいでしょう。
また、PC画面でも要素の幅が広くなりすぎないように、ブレイクポイントに合わせて最大幅を調整しておきましょう。

CSS

[popover] {
  max-width: calc(100% - 20px);
}

@media screen and (min-width:768px) {

  [popover] {
    max-width: calc(768px - 20px);
  }

}


サンプルはモバイルフレンドリーでの記述で、ブレイクポイントを「768px」としています。
20px引く部分は、Sassの変数やCSSのカスタムプロパティ(CSS変数)を使って管理してもいいでしょう。

display:noneによるSEOへの影響は?

display:noneで非表示とした要素は、ユーザーからは見れませんが検索エンジンのクローラーは把握できるという点や、SEO上の評価については不透明なこと、また隠しテキストや隠しリンクとしてクローキングのガイドラインに反する恐れがあるため、サイトの評価が下がる可能性があります。
ただ、popover属性は制作段階で意図的にdisplay:noneにするわけではなくHTMLの仕様になりますので、ペナルティの対象にはなりにくいとは考えられます。

ペナルティ対象に関するガイドラインはあるものの明確な答えはありませんので、あまり乱用せずにユーザー体験の向上のために、必要性を考えて使っていきましょう。

クロールさせる必要のないお問い合わせページ(確認ページやサンクスページ含む)や、会員制などのクローズドサイトなどでは、display:noneを気にせず利用することができるかと思います。

まとめ


以下、これまでのポップオーバーUIの実装の動きになります。
動画(5分50秒)



コンテンツ内のとある内容に対して詳しく説明していく場合は、しっかり1ページ作成して情報を伝えなければいけませんが、補足情報のような数行の文章の内容の場合では、わざわざページ遷移せずにポップオーバーで見れるようにしてあげれば、ユーザーは必要な情報へ素早くアクセスできることでしょう。