Communitygithub.com

stopsopa/skill-popover-api

提供強化原生 Popover API 的 CSS 樣式與定位方案,支援點擊或滑鼠懸停觸發,並可整合至任何前端框架。

skill-popover-api 是什麼?

這個技能以一個核心 CSS 檔案(assets/popover.css)為基礎,擴充了原生 HTML Popover API 的功能。它透過 `[data-popover]` 屬性啟用自訂樣式,讓開發者能更輕鬆地控制彈出視窗相對於觸發錨點元素的位置。支援多種定位類別(如上、下、左、右、中央及角落對齊),並能處理點擊(popovertarget)與滑鼠懸停(interestfor)兩種觸發模式。此技能完全與框架無關,無論是 Vanilla HTML、React、Angular 或 Svelte 都能直接套用,只需確保 CSS 已載入瀏覽器環境。此外,它也保留了原生 Popover API 的全部特性,例如透過 `popover="manual"` 實現僅透過按鈕關閉,或讓多個觸發元素指向同一個彈出視窗。對於不確定該選用哪個定位類別的使用者,技能提供了互動式 Demo 頁面以便視覺化比較。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add stopsopa/skill-popover-api

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

如果該檔案相對於我們的本地副本有所更新,那麼我們的本地副本也必須更新。

當第一次被要求使用 popover api 時,首先從將檔案 assets/popover.css 複製到專案中的某處開始。

合理的做法是諮詢使用者該檔案應該確切複製到專案的哪個位置,以及如果情況不明確的話,應該以何種方式載入它。

但基本上它只是一個簡單的平面 css 檔案,所以如果框架中有可以載入它的地方,只需遵循合理的標準即可。 只是基於人體工學的原因,請盡量避免載入它兩次。

當點擊錨點時彈出視窗應顯示

當使用我們的 core-css 來定位彈出視窗時,基本結構如下:

<button popovertarget="mypopover2">切換彈出視窗</button>
<div id="mypopover2" popover data-popover>
  彈出視窗內容
  <button popovertarget="mypopover2" popovertargetaction="hide">關閉</button>
</div>

在上面的範例中,我們有一個作為錨點的按鈕。按鈕點擊一次後會顯示彈出視窗(具有 [popover] 屬性的元素),再點擊一次則會隱藏彈出視窗。

但是,在彈出視窗內部點擊並不會隱藏它,除了「關閉」按鈕——它會將其關閉。

此外,在彈出視窗外部點擊將會隱藏該彈出視窗。

當您遵循此範例的結構時,它並不會做任何超出標準 popover api 功能的事情。 並且可以隨意根據使用者案例進行任何適當的修改。

注意:在此定義「關閉」按鈕是可選的,即使沒有它,所有功能也能 100% 正常運作。

因此,此 html 結構是預設佈局。

這裡的主要啟用者是屬性 'data-popover',這是啟動 assets/popover.css 樣式的屬性,主要負責將彈出視窗相對於錨點元素進行定位。

您可以不添加屬性 [data-popover],但這樣您將失去我們的自訂樣式,彈出視窗會像常規的原生元素一樣運作。 當沒有添加屬性 [data-popover] 時,您使用的是標準的原生 popover api,這個技能可能無法提供任何幫助。只需使用標準的 popover api 實作來執行您需要的操作。

但重點是,屬性 [data-popover] 作為明確的區分,用於區分我們使用此技能提供的樣式來處理 popover api,還是手動處理它。因此,當未指定 [data-popover] 時,我們的 css 將不會干擾您的手動 popover api 實作。

一般而言,請隨意使用 [data-popover] 來遵循我們的樣式,或者當您偏好使用原始的原生 popover api 時則避免使用它。

本文檔中呈現的範例可以透過任何通常與常規原生 popover api 一起使用的其他 javascript 和 html api 來控制。

<button popovertarget="mypopover3">切換彈出視窗</button>
<div id="mypopover3" popover="manual" data-popover>
  我們的彈出視窗內容
  <button popovertarget="mypopover3" popovertargetaction="hide">關閉</button>
</div>

在這裡,我們只會在點擊「關閉」按鈕時關閉。

主要的變更是 popover="manual"——當彈出視窗處於手動模式時,我們只能透過 js 或點擊具有 popovertargetaction="hide" 的元素來關閉它。

在所有範例中,對於用於實作單一彈出視窗的 div 結構,請始終保持 id 唯一。 但也讓 popovertarget 始終指向該特定的 id,以使這些 dom 元素能夠協同工作。

注意:不過在標準的 popover api 中,可以有多個錨點指向同一個彈出視窗。如果需要,這是自然允許的。

<button popovertarget="mypopover4">切換彈出視窗</button>
<div id="mypopover4" popover data-popover>
  彈出視窗內容
  <button popovertarget="mypopover4" popovertargetaction="hide">關閉</button>
</div>
<div class="container one">
  <button class="toolbar-button" interestfor="popover-b"><b>B</b></button>
  <button class="toolbar-button" interestfor="popover-i"><i>I</i></button>
  <button class="toolbar-button" interestfor="popover-u"><u>U</u></button>
</div>

<div class="container two">
  <button class="toolbar-button" interestfor="popover-b"><b>B</b></button>
  <button class="toolbar-button" interestfor="popover-i"><i>I</i></button>
  <button class="toolbar-button" interestfor="popover-u"><u>U</u></button>
</div>

<span popover="" id="popover-b" data-popover class="bottom">粗體</span>
<span popover="" id="popover-i" data-popover>斜體</span>
<span popover="" id="popover-u" data-popover>底線</span>

上面有兩組容器 -> class="container"。(使用單獨的類別 'one' 和 'two')

每個容器有 3 個按鈕。

每個按鈕都有指向 3 個彈出視窗 id 的 'interestfor' 屬性。

請注意,我們有 2 個容器,每個容器有 3 個按鈕,但只有 3 個彈出視窗。這實際上說明了這是關係: 多個懸停的元素可以觸發顯示同一個彈出視窗——這是可以且允許的。

最重要的是:使用屬性 'interestfor' 而不是 'popovertarget' 將會改變彈出視窗的顯示方式。

使用 'interestfor' 將會在滑鼠懸停時顯示彈出視窗。 而使用 'popovertarget' 則會在點擊時顯示彈出視窗。

為了決定彈出視窗相對於錨點元素應該出現在何處,我們將使用我們的 core-css 檔案。

如前所述,我們的 core-css 檔案要求我們在 [popover] 元素上添加 [data-popover] 屬性。

從那時起,控制彈出視窗相對於錨點元素的位置,是透過向具有 [data-popover] 屬性的元素添加 css 類別來完成的。

以下是可用的類別:

  • 類別 top:定位在錨點上方,水平居中。(這是預設樣式,即使沒有向 'data-popover' 元素添加類別時也會使用)

  • 類別 bottom:定位在錨點下方,水平居中。(這是預設樣式,即使沒有向 'data-popover' 元素添加類別時也會使用)

  • 類別 left:定位在錨點左側,垂直居中。(這是預設樣式,即使沒有向 'data-popover' 元素添加類別時也會使用)

  • 類別 right:定位在錨點右側,垂直居中。(這是預設樣式,即使沒有向 'data-popover' 元素添加類別時也會使用)

  • 類別 top-left:定位在錨點上方,其左邊緣與錨點的左邊緣對齊。

  • 類別 top-right:定位在錨點上方,其右邊緣與錨點的右邊緣對齊。

  • 類別 bottom-left:定位在錨點下方,其左邊緣與錨點的左邊緣對齊。

  • 類別 bottom-right:定位在錨點下方,其右邊緣與錨點的右邊緣對齊。

  • 類別 center:直接定位在錨點上方,水平和垂直都居中。

  • 類別 topleft:彈出視窗的右下角接觸到錨點的左上角

  • 類別 topright:彈出視窗的左下角接觸到錨點的右上角

  • 類別 bottomleft:彈出視窗的右上角接觸到錨點的左下角

  • 類別 bottomright:彈出視窗的左上角接觸到錨點的右下角

  • 類別 left-top:定位在錨點左側,其頂部邊緣與錨點的頂部邊緣對齊。

  • 類別 left-bottom:定位在錨點左側,其底部邊緣與錨點的底部邊緣對齊。

  • 類別 right-top:定位在錨點右側,其頂部邊緣與錨點的頂部邊緣對齊。

  • 類別 right-bottom:定位在錨點右側,其底部邊緣與錨點的底部邊緣對齊。

最好從使用者那裡獲取關於使用哪個定位類別的資訊,但如果使用者僅描述特定的定位方式,則嘗試根據描述自動找到最佳類別。

如果使用者或 AI 對該使用哪個類別感到困惑,則建議使用者前往主要的 github 頁面 Demo 頁面,那裡以互動方式展示了類別的行為:

https://stopsopa.github.io/skill-popover-api/demo/index.html

使用者將能夠觀察哪個類別為所討論的彈出視窗提供了最佳的定位行為。

從該 Demo 頁面,使用者只需點擊絲帶小部件一次,即可進入主 github 頁面了解更多詳細資訊。

使用 'data-popover' 屬性來啟動我們的 core-css 樣式的 html 結構是通用的。

它可以在 vanilla html、react、angular、svelte 等中使用。

只要底層基本 html 與上述範例中呈現的內容相符,並且 assets/popover.css 已在瀏覽器環境中載入,它就會運作。

偶爾,它可能需要使用一些標準的 react 包裝元件或任何特定於給定框架的其他結構/形式進行包裝。

只需在上述範例的基礎上,為給定的框架上下文執行正確的操作即可。

相關技能