CSS的未來:Popover API

CSS的未來:Popover API

在這篇文章中,我們要看的不是一個而是兩個即將出現在CSS中的令人興奮的新東西,第一個是Popover API。雖然我認為它本身很好,但當它與錨點定位搭配使用時,我們能做的事情就非常非常酷了。在寫這篇文章的時候,這兩個功能都只在非穩定的瀏覽器中可用。

什麼是Popover API?

Popover API是一個強大的工具,為開發人員提供了一個一致和靈活的方式來顯示網頁上的彈出式內容。無論你喜歡宣告性的HTML屬性還是JavaScript控制,這個API都能滿足你的需求。

在網路上,在其他內容的頂部呈現內容是很常見的,如果你願意的話,在top-layer,以引起使用者對重要資訊或行動的注意。你可能已經遇到了各種術語,如彈出式視窗或對話方塊。

HTML屬性

  • popover
    • auto (default) – 這意味著當點選外部或按下esc時,彈出視窗可以被解散,同時其他彈出視窗也會為這個新的彈出視窗關閉。
    • manual – 當手動時,彈出視窗只能被手動關閉(使用JS或HTML關閉動作)。
  • popovertarget
    • [id] – 這個屬性可以放在一個 button 上,讓它控制一個彈出視窗,該屬性的值應該是目標的 id
  • popovertargetaction
    • toggle (default) – 按下帶有 popovertargetbutton  將對彈出視窗執行該動作。在這種情況下,如果隱藏,彈出視窗將顯示,如果顯示,則隱藏。
    • hide – 設定 popovertarget 為顯示無。
    • show – 設定 popovertarget 為顯示塊。
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<button popovertarget="menu" popovertargetaction="toggle">Menu</button>
<nav id="menu" popover="auto">
<ul>
<li><a href="/items/1">Item 1</a></li>
<li><a href="/items/1">Item 2</a></li>
<li><a href="/items/1">Item 3</a></li>
</ul>
</nav>
<button popovertarget="menu" popovertargetaction="toggle">Menu</button> <nav id="menu" popover="auto"> <ul> <li><a href="/items/1">Item 1</a></li> <li><a href="/items/1">Item 2</a></li> <li><a href="/items/1">Item 3</a></li> </ul> </nav>
<button popovertarget="menu" popovertargetaction="toggle">Menu</button>
<nav id="menu" popover="auto">
  <ul>
    <li><a href="/items/1">Item 1</a></li>
    <li><a href="/items/1">Item 2</a></li>
    <li><a href="/items/1">Item 3</a></li>
  </ul>
</nav>

CSS 偽元素和類

  • ::backdrop – 這是一個偽元素,它填滿了彈出式視窗後面的整個螢幕,對它進行造型可以讓你改變顏色,甚至增加模糊度。
  • :popover-open – 這是一個偽類,當彈出視窗元素被開啟時,它會被應用到該元素上,我們可以用它來新增開啟動畫。
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#menu {
border: 0;
margin-right: 0;
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
max-width: 100vw;
width: 200px;
height: 100%;
}
#menu ul {
list-style: none;
padding: 0;
}
#menu ul li {
padding: 1ch;
}
#menu::backdrop {
background-color: rgba(200, 200, 200, 0.5);
backdrop-filter: blur(2px);
}
#menu:popover-open {
animation: slideIn 150ms ease-in-out;
}
@keyframes slideIn {
0% {
translate: 100% 0 0;
}
100% {
translate: 0 0 0;
}
}
#menu { border: 0; margin-right: 0; box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); max-width: 100vw; width: 200px; height: 100%; } #menu ul { list-style: none; padding: 0; } #menu ul li { padding: 1ch; } #menu::backdrop { background-color: rgba(200, 200, 200, 0.5); backdrop-filter: blur(2px); } #menu:popover-open { animation: slideIn 150ms ease-in-out; } @keyframes slideIn { 0% { translate: 100% 0 0; } 100% { translate: 0 0 0; } }
#menu {
border: 0;
margin-right: 0;
box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
max-width: 100vw;
width: 200px;
height: 100%;
}
#menu ul {
list-style: none;
padding: 0;
}
#menu ul li {
padding: 1ch;
}
#menu::backdrop {
background-color: rgba(200, 200, 200, 0.5);
backdrop-filter: blur(2px);
}
#menu:popover-open {
animation: slideIn 150ms ease-in-out;
}
@keyframes slideIn {
0% {
translate: 100% 0 0;
}
100% {
translate: 0 0 0;
}
}

JavaScript控制元件和事件

我知道這篇文章主要是關於CSS的新的和令人興奮的東西,但如果不談談JS,那就太可惜了。

控制元件

  • PopoverElement.hidePopover() – 更新彈出式視窗元素並將其移至隱藏狀態。
  • PopoverElement.showPopover() – 更新popover元素並將其移至顯示狀態。
  • PopoverElement.togglePopover() – 更新popover元素並在其隱藏和顯示狀態之間切換。

事件

  • beforetoggle – 視覺上發生狀態變化之前觸發的事件。
  • toggle – 視覺上發生狀態變化後觸發的事件。
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const popover = document.querySelector('#menu[popover]');
popover.addEventListener('beforetoggle', () => {
// I triggered first before anything visually happened.
});
popover.addEventListener('toggle', () => {
// I triggered after the toggle had happened visually.
});
const popover = document.querySelector('#menu[popover]'); popover.addEventListener('beforetoggle', () => { // I triggered first before anything visually happened. }); popover.addEventListener('toggle', () => { // I triggered after the toggle had happened visually. });
const popover = document.querySelector('#menu[popover]');
popover.addEventListener('beforetoggle', () => {
// I triggered first before anything visually happened.
});
popover.addEventListener('toggle', () => {
// I triggered after the toggle had happened visually.
});

Demo

這是一個簡單的對話方塊演示,我選擇在這個例子中不包含任何JavaScript,只是為了展示它可以真正的簡單化。

如果你的瀏覽器還不支援 popover ,這裡有一個後備GIF。

簡單的對話方塊演示動畫

什麼是錨點定位?

錨點定位還沒有在MDN上出現,所以這確實是一些實驗性的東西。我將盡力解釋它的作用以及如何使用它。

目前,如果你想讓一個元素在另一個元素旁邊呈現,最簡單的方法是用JavaScript計算出目標元素的位置,然後將錨定元素設定為絕對位置,並設定頂部、右側、底部或左側屬性。這種方法是可行的,但 “少用JavaScript就好”,所以錨可以讓你把元素的位置儲存在一個CSS變數中。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#anchor {
anchor-name: --test-anchor;
}
.anchored-element {
position: absolute;
right: anchor(--test-anchor left);
top: anchor(--test-anchor center);
transform: translateY(-50%);
}
#anchor { anchor-name: --test-anchor; } .anchored-element { position: absolute; right: anchor(--test-anchor left); top: anchor(--test-anchor center); transform: translateY(-50%); }
#anchor {
anchor-name: --test-anchor;
}
.anchored-element {
position: absolute;
right: anchor(--test-anchor left);
top: anchor(--test-anchor center);
transform: translateY(-50%);
}

你會注意到這個新的 anchor CSS函式。它接受一個CSS變數和一個位置,然後返回位置,你甚至可以在一個 calc 中使用這個值來做更復雜的位置。

Demo

這裡有一個小的演示,展示了工具提示的建立,其目的是為了簡單化,只展示一個簡單的實現。

再說一遍,這裡有一個後備的GIF,因為我相信錨點仍然是一個有點遠的地方。

工具提示Gif動畫

我們怎樣才能把這些東西放在一起使用呢?

網路已經存在了很長時間,並且完全向後相容,這很好,但確實導致了一些問題,比如不能定製 select 組合框元件。我相信你們中的許多人都有過這樣的兩難選擇:是從頭開始寫一個新的組合框來配合特定的設計,還是找一個別人已經做出來的組合框,但失去了一些定製能力。

PopoverAnchor Position 結合起來,我想我們也許能夠做出一個漂亮的組合框,我們可以按照自己喜歡的方式來構建,而不必擔心可訪問性和定位問題。讓我們看看我們是否能做到這一點。

我們對可訪問性做了什麼?

有一個由W3C的可愛的人制作的網站,它為各種不同的使用情況(包括組合框)提供了所有的Aria模式。我將瀏覽這個網站,並檢視本地選擇元素的作用。

我知道Aria模式網站已經建立了一段時間,但我無法強調它有多麼神奇和有用,我覺得它有點像一個最保守的祕密,但每個人都應該使用它。

Demo

所以,我們在這裡,最後,演示。我把Popover API和Anchor定位結合起來,製作了一個組合框,我們可以隨心所欲地設計。

我不得不使用一些JS,以確保它對鍵盤友好,並確保按鈕中的文字更新,如果你們有什麼想法,我們可以用更少的JS來做這些事情,我很想聽聽。

最後,希望有一天我們都能回過頭來看看這個帖子,看到一切都在運作。

trg90wwomhyk8c17s1e8

小結

這就結束了,Popover API應該很快就會開始在穩定的瀏覽器中出現,但錨點定位可能還需要一段時間。話雖如此,但現在確實是一個令人興奮的時代。很多以前需要黑客解決的任務現在都得到了解決,使我們能夠探索更多創造性的可能性

評論留言