發布日期:2024 年 11 月 6 日
在 Chrome 131 版中,你有更多方式可以設定 <details>
和 <summary>
元素的結構樣式。您現在可以在建構揭露聲明或摺疊式小工具時使用這些元素。
具體來說,Chrome 131 中引進的變更可讓您在這些元素上使用 display
屬性,並新增 ::details-content
擬元素,為展開和收合部分套用樣式。
瀏覽器支援
在 <details>
元素上設定 display
過去無法變更 <details>
元素的顯示類型。這項限制現已放寬,您可以使用格線或 Flex 版面配置在 <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
類型在通用 Analytics 樣式表單中設為 block
,而先前則為 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
擬造動畫。