發布日期: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
擬造動畫。