Popover = hint

發布日期:2025 年 2 月 26 日

Chrome 133 在現有的彈出式視窗功能上,推出了新模式:popover="hint"。這個由瀏覽器管理的模式可啟用新的堆疊內容,簡化建立工具提示和類似的暫時浮動元素。這有助於減少開發人員的工作量,同時維持設計彈性。

簡介和歷史

在 Chrome 114 中推出的 Popover API,可讓您建立可存取的浮動 UI,例如選單和工具提示。根據預設,popover="auto" 會為您處理輕鬆關閉功能和焦點管理,無須額外編寫指令碼,如介紹 Popover API所述。開啟 popover="auto" 彈出式視窗時,所有其他非父項的彈出式視窗都會關閉,這可讓 API 以最合乎人體工學的方式運作。popover="auto"

彈出式視窗關閉其他彈出式視窗

<div id="p1" popover>First Popover</div>
<button popovertarget="p1">Open popover 1</button>
<div id="p2" popover>Second Popover</div>
<button popovertarget="p2">Open popover 2</button>

在這個範例中,開啟 彈出式視窗 2 會關閉 彈出式視窗 1,因為 popover="auto" 一次只允許開啟一個這類彈出式視窗。

雖然這項行為適用於選單和對話方塊,但如果需要同時顯示多種浮動式 UI,就可能會發生問題。舉例來說,如果選單和工具提示都使用 popover="auto",就可能發生衝突,開啟工具提示時會關閉選單。這可能看起來不常見,但在現代應用程式樣式的 UI 中,這種情況相當常見。舉例來說,github.com 標頭的選單會使用彈出式選單和工具提示,讓兩者在特定情況下同時顯示:

已開啟的選單。
GitHub 選單。

解決這個問題的方法之一,是使用 popover="manual" 做為工具提示元素,這樣就能透過指令碼完全控制彈出式視窗。不過,這需要重新實作堆疊行為、輕鬆關閉和焦點管理,而這些正是 Popover API 設計用來處理的工作。因此,我們開始探索如何擴充 API,以提供這項缺少的功能。

透過開發人員研究,我們找出了兩種常見的堆疊內容:

  • 永久性 UI:例如選單和對話方塊。
  • 暫時性 UI:例如懸停卡和工具提示。

為了同時支援這兩種情況,popover="hint" 會引入第二個堆疊,與 popover="auto" 不同,確保即使出現工具提示,選單仍會保持開啟狀態。這種做法並未為不同 UI 類型引進多個堆疊內容,這會讓 z-index 重複出現,而是只定義兩個大類別:持續性 UI (auto) 和暫時性 UI (hint),讓彈出式視窗更為簡單。這樣一來,彈出式視窗就能兼顧彈性和避免重複出現使用彈出式視窗時遇到的問題。

新值的行為

popover="auto"popover="hint" 都支援輕鬆關閉功能,也就是說,當使用者點選畫面外部,或按下鍵盤上的 Esc 時,這些視窗就會自動關閉。就這方面而言,兩種樣式都相同。

在強制隱藏其他彈出式視窗方面,popover="auto" 會在開啟時關閉所有其他 autohint 彈出式視窗,確保一次只會有一個這類彈出式視窗處於活動狀態 (巢狀彈出式視窗是唯一例外,詳情請見下文)。另一方面,popover="hint" 只會強制隱藏其他 hint 彈出式視窗,讓選單和工具提示保持開啟並共存。

兩者最大的差異在於巢狀行為。popover="auto" 支援巢狀結構,可讓子彈出式視窗在其他父項彈出式視窗中保持開啟狀態。popover="hint" 有特殊的巢狀行為,這就是「堆疊」的用途。當 hint 彈出式視窗位於 auto 彈出式視窗中時,它會加入 auto 堆疊,以維持內容相關群組,也就是說,它會保持開啟狀態,直到其他 autohint 彈出式視窗導致它強制隱藏為止。這可提供直覺的行為,即工具提示不會中斷其他選單或彈出式視窗。

最後,對於非常不同的用途,您可以使用 popover="manual",因為它不具備任何內建行為,讓您可以明確定義所需的功能和行為。

popover="auto" popover="hint" popover="manual"
關閉燈光
強制隱藏: 不相關的 autohint 不相關的 hint Nothing
巢狀結構: 特殊 (如先前所述) 不適用:沒有關閉燈光的選項

懸停觸發

常見的使用者體驗模式是讓工具提示和懸停卡以懸停觸發。將滑鼠游標懸停在感興趣的元素上一段時間,就會顯示懸浮資訊卡。目前,您必須透過 JavaScript 實作這項行為,例如為 mouseentermouseleave 事件新增監聽器。不過,我們正在開發另一個 API,應該可以讓懸停觸發動作變成宣告式:Interest Invokers API

這個 API 仍在開發中,但大致概念是將名為 interesttarget 的屬性新增至許多元素類型,為這些元素提供懸停觸發行為:

<a interesttarget="my-hovercard" href="...">
  Hover to show the hovercard
</a>
<span popover="hint" id="my-hovercard">
  This is the hovercard
</span> 

使用上述 HTML 時,將滑鼠游標懸停在 <a> 連結上,系統就會自動顯示 my-hovercard 彈出式視窗。將游標移出該元素後,系統就會隱藏彈出式視窗。而且完全不需要 JavaScript!

範例

<button>An interesting button</button>
<div popover="hint">More info about the button</div>
[popover] {
  margin: 0;
  inset: auto;
  position-area: bottom right;
}
const button = document.querySelector('button');
const popover = document.querySelector('[popover]');

button.onmouseenter = () => {
  setTimeout(() => {
    popover.showPopover({source: button});
  }, 500);
}

button.onmouseleave = () => {
  setTimeout(() => {
    popover.hidePopover();
  }, 500);
}
含有工具提示的按鈕。
立即試用。

這個範例使用 popover="hint" 建構基本工具提示,當滑鼠游標懸停在按鈕上時,可提供更多相關資訊。懸停啟用功能是由 mouseentermouseleave 的事件處理常式提供,且有 0.5 秒的簡單延遲時間。請注意,這個範例未處理以下幾個細節:

  1. 將滑鼠游標懸停在彈出式視窗上,並不會防止滑鼠游標離開觸發元素時關閉彈出式視窗。因此,您無法複製或貼上彈出式視窗中的文字。
  2. 沒有「去抖動」功能:只要將滑鼠游標懸停在按鈕上幾分之一秒,就會觸發彈出式視窗,即使在延遲時間結束前快速移開滑鼠游標,也一樣會觸發彈出式視窗。在這種情況下,工具提示會快速開啟和關閉,並且「閃爍」。
  3. 這個範例完全無法存取:任何不使用滑鼠的使用者都無法存取工具提示內容。

這些缺點可以透過額外的 JavaScript 修正。舉例來說,您需要新增 focus (或許還有 keydownkeyup) 事件處理常式),才能支援以鍵盤啟用彈出式視窗。如要瞭解如何正確處理相關事項,確保工具提示可供存取,請參閱 Sarah Higley 撰寫的這篇優質網誌文章。所有這些問題 (以及更多問題) 都會由 Interest Invokers API 以宣告方式自動處理。

瞭解詳情

詳情請參閱功能說明HTML 規格