質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

2回答

296閲覧

HTMLのpopoverの位置の指定方法

kasuta

総合スコア1

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

1グッド

0クリップ

投稿2025/05/16 04:51

編集2025/05/16 09:55

実現したいこと

HTMLのbuttonをクリックしたときに、そのbuttonの傍にpopover属性を指定した要素を表示させたい。
表示/非表示はjavascriptで制御する。

[5/16 17:33 追記]
javascriptで制御したい理由は、buttonをクリックされたら実行されるjavascriptの処理結果に応じてpopoverを表示するかしないかを変えたい、あるいは表示内容を変更したいからです。

発生している問題・分からないこと

Javascriptを使用せずに自動的に表示させる場合には、buttonの傍に表示されます。
JavascriptのshowPopover()で表示されると離れた位置に表示されてしまいます。

popup位置の基準となる要素を何らかの方法で指定する必要があるのかがわかりません。
htmlの属性またはcssの記述が不足しているのでしょうか?

該当のソースコード

html

1<div style="position: relative;"> 2 3 <div id="pop1" style="margin:0; inset:0; position-area:top;" popover > 4 <div>あいうえお<br />かきく</div> 5 </div> 6 7 <button id="btnOK" style="margin:100px;" popovertarget="pop1"> 8 <span>意図した通りの要素の上になる</span> 9 </button> 10 11 <button id="btnFail" style="margin:100px;"> 12 <span>画面下になってしまう</span> 13 </button> 14 15 <script> 16 document.querySelector("#btnFail").addEventListener("click", (ev) => { 17 document.querySelector("#pop1").hidePopover(); 18 document.querySelector("#pop1").showPopover(); 19 }); 20 </script> 21</div>

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Popover anchor positioningで説明されているposition-areaを使用してるがjavascriptからは効果がない。

javascriptでの場合に対象とする要素が指定できていないのではと考えていますが、開発者ツールでみても違いが見つけられません。

補足

chrome 136
edge 136
(firefoxではまったく位置が合わない、safariでは試せていないが、今回の質問ではchromium系のみでよい)

得られた回答を参考に実現できたコード

[5/16 17:53 追記]
クリックされた(スクリプト処理後の)時点での対象のpopovertarget属性で判定されるようなので、非同期のawaitしてしまうと成功しませんでしたが、属性を書き換えてからclick()を呼び出すことで遅延させることができました。

html

1 document.querySelector("#btnFail").addEventListener("click", async (ev) => { 2 3 const btn = ev.currentTarget; 4 5 if (btn.hasAttribute("popovertarget")) { 6 return; 7 } 8 9 btn.innerText = "処理中"; 10 const result = await new Promise((r) => setTimeout(r, 1000, (Math.random() < 0.5))); 11 btn.innerText = result ? "合格" : "不合格"; 12 if (result) { 13 btn.setAttribute("popovertarget", "pop1"); 14 } 15 else { 16 btn.setAttribute("popovertarget", "pop2"); 17 } 18 19 btn.click(); 20 btn.removeAttribute("popovertarget"); 21 });

得られた回答を参考に実現できたコード 2

[5/16 18:20 追記]
HTMLとCSSでの関連は、styleにposition-anchorposition-nameの値が一致する組み合わせをつければ良さそうなので、HTMLで書くと以下のように。

html

1<div id="pop1" 2 style="position-anchor: --testAnchor; margin:0; inset:0; position-area:top; background-color: green; color: white;" 3 popover> 4 <div>合格</div> 5</div> 6<button id="btnFail" style="anchor-name:--testAnchor; margin:100px;"> 7 <span>2</span> 8</button>

これをjavascriptで実現すると

javascript

1document.querySelector("#btnFail").addEventListener("click", async (ev) => { 2 3 const btn = ev.currentTarget; 4 btn.innerText = "処理中"; 5 6 const result = await new Promise((r) => setTimeout(r, 1000, (Math.random() < 0.5))); 7 const pop = document.querySelector(result ? "#pop1" : "#pop2"); 8 9 const anchorName = "--testAnchor" + Date.now().toString(); 10 btn.style.anchorName = anchorName; 11 pop.style.positionAnchor = anchorName; 12 pop.showPopover(); 13});

とすることでshowPopover()でも任意に指定したボタンの傍に表示させることができるようになりました。

得られた回答を参考に実現できたコード 3

[5/16 18:55 追記]
showPopoverの引数で指定できる!!!

javascript

1document.querySelector("#btnFail").addEventListener("click", async (ev) => { 2 3 const btn = ev.currentTarget; 4 btn.innerText = "処理中"; 5 6 const result = await new Promise((r) => setTimeout(r, 1000, (Math.random() < 0.5))); 7 const pop = document.querySelector(result ? "#pop1" : "#pop2"); 8 pop.showPopover({ source: btn }); 9});
Lhankor_Mhy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

 仕様を見てみました。


 position-anchorが初期値のautoである時は、implicit anchor element が anchor element として扱われます。

https://drafts.csswg.org/css-anchor-position-1/#position-anchor

 この implicit anchor element は、ポップアップ表示処理の呼び出し元によって変わるようです。くわしくは、以下の24番をご覧ください。

https://html.spec.whatwg.org/multipage/popover.html#show-popover


 つまり、「popup位置の基準となる要素を何らかの方法で指定する必要があるのかがわかりません」の答えは、「必要あります。position-anchorを指定してください」になります。

参考:CSS Anchor Positioning 仕様の紹介


追記

 よくMDNを見ると英語版はいろいろ追加されているのですね…… showPopover()のオプションとか知りませんでした。こちらのやり方でもいいのだろうと思います。Chromeでも2025年2月の実装なので、対応環境に不安があると思いますが……

The browser creates an implicit anchor reference between the two, making it very convenient to position popovers relative to their controls using CSS anchor positioning.
HTMLElement: showPopover() method - Web APIs | MDN

(訳)ブラウザは2つのエレメント間に暗黙のアンカーを作成するため、CSSアンカーポジショニングを使用してポップオーバーの位置をコントロールするのに、とても便利です。


質問の追記に対して追記

buttonをクリックされたら実行されるjavascriptの処理結果に応じてpopoverを表示するかしないかを変えたい、あるいは表示内容を変更したいから

動機がこちらでしたら、popovertarget経由で開いて、beforetoggleイベントを拾って処理する、というのもアリだと思います。

投稿2025/05/16 07:55

編集2025/05/16 08:44
Lhankor_Mhy

総合スコア37438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kasuta

2025/05/16 09:18

いろいろ情報ありがとうございます。 暗黙のアンカーという概念があることが判りました。クリックされたボタンが暗黙のアンカーになるのですね。
kasuta

2025/05/16 09:37 編集

position-anchorとposition-nameの書き換えすることで、showPopoverから表示できるようになりましたので、ベストアンサーに選ばせていただきました。
Lhankor_Mhy

2025/05/16 09:36

質問の追記のコードを拝見しましたが、追記に書いた通り、普通にdocument.querySelector("#pop1").showPopover({source: ev.target});とした方が楽そうに思います。 ブラウザ対応を気にされているのであればすみません。
kasuta

2025/05/16 09:51

showPopoverに引数があった。。。見た時にはなかったと思いたいですが、完全に見落としていたようです。 試したところ、popoverのstyleにposition-anchorが指定されている状態だと、引数指定してもダメになるようですね。
kasuta

2025/05/16 09:59

2025/5/16現在、MDNの日本語版のshowPopoverのページでは引数の存在の記載がありませんが、英語版には記載されています。
Lhankor_Mhy

2025/05/16 10:08

そうなんですよね、英語版にはいろいろ追記がされていて驚きました。まだ仕様が固まってないのでこれからもいろいろ変更されそうですよね。
guest

0

そもそもpopoverをjsで制御する必要あります?

html

1<div style="position: relative;"> 2 <div id="pop1" style="margin:0; inset:0; position-area:top;" popover> 3 <div>あいうえお<br />かきく</div> 4 </div> 5 <button style="margin:100px;" popovertarget="pop1"> 6 <span>1</span> 7 </button> 8 <button style="margin:100px;" popovertarget="pop1"> 9 <span>2</span> 10 </button> 11 <button id="btnFail" style="margin:100px;"> 12 <span>3</span> 13 </button> 14<script> 15btnFail.setAttribute('popovertarget','pop1'); 16</script> 17</div>

投稿2025/05/16 07:13

yambejp

総合スコア117719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kasuta

2025/05/16 08:50 編集

javascriptで制御したいのは、javascriptの処理した結果に応じて表示を切り変えたいからです。 popovertarget属性を設定してやるとうまくいくことがヒントになりました。
yambejp

2025/05/16 09:28

popover機能はまだ実装されてから歴史が浅いので正しく動作する想定でWEBに組み込むのは早計でしょうね・・・dialogタグもブラウザ間の差異がなくなるのに数年かかったイメージがあります
kasuta

2025/05/16 09:37 編集

clickの再呼び出しというちょっとよくないコードになってしまいますが解決できました。 ベストアンサーは別の方を選ばせていただきましたが、こちらの回答も非常に参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問