發布日期:2024 年 11 月 6 日
從 Chrome 131 開始,您有更多選項可設定 <details>
和 <summary>
元素的樣式結構。現在建構揭露或手風琴式小工具時,可以使用這些元素。
特別是 Chrome 131 中導入的變更,可讓您在這些元素上使用 display
屬性,並新增 ::details-content
虛擬元素,為展開和收合的部分設定樣式。
在 <details>
元素上設定 display
過去無法變更 <details>
元素的顯示類型,這項限制現已放寬,因此您可以在 <details>
元素上使用格線或彈性版面配置等。
在以下範例中,互斥的摺疊手風琴包含並排放置的數個 <details>
元素。展開其中一個 <details>
元素時,其內容會放在 <summary>
旁邊。
示範
錄影
方法是在 <details>
元素上使用彈性版面配置,並採用下列 CSS:
details {
display: flex;
flex-direction: row;
}
也允許其他顯示值,例如 grid
。
使用 display: inline
的注意事項
display
值可能會導致非預期結果,即 inline
。這並非因為無法運作,而是因為 HTML 剖析器有其限制。
將 <details>
元素放在段落內時,HTML 剖析器會強制先關閉開啟的段落,如 HTML 標準第 13.2.6.4.7 節所定義:
標記名稱為下列其中之一的開始標記:「address」、「article」、「aside」、「blockquote」、「center」、「details」、「dialog」、「dir」、「div」、「dl」、「fieldset」、「figcaption」、「figure」、「footer」、「header」、「hgroup」、「main」、「menu」、「nav」、「ol」、「p」、「search」、「section」、「summary」、「ul」
如果開啟的元素堆疊在按鈕範圍內有 p 元素,請關閉 p 元素。 插入權杖的 HTML 元素。
因此,無論您是否已設定 display: inline
,<details>
都會朝方塊方向流動。
舉例來說,下列標記
<p>Hello <details>…</details> world</p>
剖析後會變成這樣:
<p>Hello </p><details>…</details> world<p></p>
您可以使用 Chrome 開發人員工具檢查剖析的標記,在這個範例中親自查看。
請注意,這僅適用於在 <p>
內巢狀結構的 <details>
。在 <div>
內的 <details>
上使用 display: inline
沒問題。
::details-content
虛擬元素
在瀏覽器中,<details>
元素是使用 Shadow DOM 實作。其中包含摘要的 <slot>
(附有預設摘要子項),以及所有其餘內容的 <slot>
,也就是 <details>
元素的所有子項 (<summary>
元素除外)。
<details>
↳ #shadow-root (user-agent)
<slot id="details-summary">
<summary>Details</summary>
<!-- The summary goes here -->
</slot>
<slot id="details-content">
<!-- All content goes here -->
</slot>
</details>
除了在 <details>
上使用更多顯示類型,現在還能使用 ::details-content
虛擬元素指定內容插槽。您可以使用這個虛擬元素,為包裝 <details>
元素內容的容器設定樣式。
details::details-content {
border: 5px dashed hotpink;
}
如要只在 <details>
元素處於開啟狀態時套用設定的樣式,請在該元素前面加上 [open]
選取器。
[open]::details-content {
border: 5px dashed hotpink;
}
建議只在 <details>
元素處於 [open]
狀態時,才將樣式套用至 ::details-content
虛擬元素。
示範
錄影
::details-content
的 display
block
類型已在 UA 樣式表設定,之前則是 display: contents
。在某些情況下,這項變更可能會對您不利,例如揭露的內容依賴 height: 100%
。如果這會造成問題,您可以將 display
型別設回 contents
,藉此解決問題,如下所示:details[open]::details-content { display: contents; }
。
為 ::details-content
虛擬元素套用動畫
您可以為 <details>
元素展開時的內容加入動畫效果。在以下範例中,寬度會從 0px
動畫化為 300px
。
::details-content {
transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
width: 0;
}
[open]::details-content {
width: 300px;
}
除了轉換 width
之外,content-visibility
屬性也需要轉換。這是因為 User-Agent 樣式表定義了未開啟和開啟狀態之間的值變化。由於該屬性是可個別動畫化的屬性,因此您需要allow-discrete
關鍵字才能運作。
加入先前分享的專屬手風琴示範,結果如下:
示範
錄影
height
也可以是動畫。如要將動畫設為 height: auto
,請使用 interpolate-size
或 calc-size()
。此外,如要防止內容溢出 ::details-content
虛擬元素,請對其套用 overflow: clip
。
::details-content {
transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
height: 0;
overflow: clip;
}
/* Browser supports interpolate-size */
@supports (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
[open]::details-content {
height: auto;
}
}
/* Fallback for browsers with no interpolate-size support */
@supports not (interpolate-size: allow-keywords) {
[open]::details-content {
height: 150px;
overflow-y: scroll; /* In case the contents should be taller than 150px */
}
}
您可以在下列示範中查看實際運作的程式碼,這個示範的靈感來自 Material UI 的手風琴。每個 <details>
元素的內容都會順暢地產生動畫效果。
示範
錄影
即使瀏覽器不支援 ::details-content
,元件仍可正常運作。訪客唯一看不到的內容是動畫。
特徵偵測
如要進行功能偵測,確認 CSS 是否支援 ::details-content
虛擬元素,請使用下列程式碼片段。
@supports selector(::details-content) {
…
}
您也可以使用這項偵測功能做為指標檢查,判斷訪客使用的瀏覽器是否支援額外的顯示值。
無障礙注意事項
導入 ::details-content
虛擬元素和變更顯示類型的功能,不會影響 <details>
元素的無障礙功能。
與先前一樣,至少在以 Chromium 為基礎的瀏覽器中,根據 HTML 標準,<details>
元素可供搜尋,且當瀏覽器嘗試捲動至隱藏內容時 (回應網頁內搜尋、ScrollToTextFragment 和元素片段導覽),會自動展開。這項設定不會變更。
不過,使用專屬手風琴選單前,請先考量這項功能對使用者是否有幫助或造成負面影響。使用專屬手風琴式選單可減少內容佔用的視覺空間,但使用者可能必須開啟多個項目才能查看所有資訊。如果使用者想同時查看多個項目,可能會感到不便。
如何設定標記樣式?
目前清單標記的樣式無法互通,因為 Gecko 和 (目前的) Chromium 採用一種方法,而 WebKit (先前與 Chromium 共用) 採用另一種方法。
這項功能可互通運作後,我們將提供更完善的控制選項,方便您設定標記的樣式。
更多示範
最後,我們準備了更多示範,歡迎參考。這些帳戶都使用 ::details-content
。
UIKit 手風琴
示範
錄影
這個範例是以 UIKit Accordion 為基礎建構而成。這段程式碼與先前分享的 Material UI 手風琴幾乎相同。
部分開啟的揭露小工具
示範
錄影
這個範例顯示部分開啟的揭露小工具,內容已顯示在畫面上。為此,content-visibility
一律會設為 visible
。height
會使用 calc-size()
產生動畫,因為這涉及計算。
::details-content {
content-visibility: visible; /* Make it always visible */
transition: height 0.5s ease;
height: 150px;
overflow: clip;
}
[open]::details-content {
height: calc-size(auto, size + 0.5rem); /* calc-size because we need to add a length */
}
為了方便設定樣式,內容會包裝在包裝函式 div 中。包裝函式 div 會套用 padding
等版面配置樣式,而 ::details-content
虛擬元素則會產生動畫效果。