更多樣式 <詳細資料> 樣式選項

發布日期:2024 年 11 月 6 日

在 Chrome 131 版中,你有更多方式可以設定 <details><summary> 元素的結構樣式。您現在可以在建構揭露聲明或摺疊式小工具時使用這些元素。

具體來說,Chrome 131 中引進的變更可讓您在這些元素上使用 display 屬性,並新增 ::details-content 擬元素,為展開和收合部分套用樣式。

瀏覽器支援

  • Chrome:131。
  • Edge:不支援。
  • Firefox:不支援。
  • Safari:不支援。

<details> 元素上設定 display

過去無法變更 <details> 元素的顯示類型。這項限制現已放寬,您可以使用格線或 Flex 版面配置在 <details> 元素上。

在以下範例中,專屬摺疊元素包含數個並排放置的 <details> 元素。展開其中一個 <details> 元素時,其內容會放在 <summary> 旁邊。

示範

錄影

Chrome 131 中https://codepen.io/web-dot-dev/pen/VwoBQjY的錄製內容

方法是在 <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 擬造元素。

示範

錄影

Chrome 131 中https://codepen.io/web-dot-dev/pen/oNKMEYv的錄製畫面

::details-contentdisplay 類型在通用 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 關鍵字才能運作。

加入先前分享的專屬摺疊式示範,結果如下:

示範

錄影

Chrome 131 中https://codepen.io/web-dot-dev/pen/XWvBZNo的錄製內容

height 也可以製作動畫。如要將動畫轉換為 height: auto,您必須使用 interpolate-sizecalc-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> 元素的內容都具有良好的動畫效果。

示範

錄影

Chrome 131 中https://codepen.io/web-dot-dev/pen/ExqpQZM的錄製內容

在未支援 ::details-content 的瀏覽器中,元件仍可正常運作。訪客唯一看不到的是動畫。

特徵偵測

如要偵測 CSS 是否支援 ::details-content 疑似元素,請使用以下程式碼片段。

@supports selector(::details-content) {
  
}

您也可以使用這項偵測功能做為指標,判斷訪客使用的瀏覽器是否支援額外的顯示值。

無障礙設計考量

導入 ::details-content 擬造元素和變更顯示類型的功能,不會影響 <details> 元素的無障礙功能。

如同先前所述,至少在以 Chromium 為基礎的瀏覽器和HTML 標準中,<details> 元素是可搜尋的,且當瀏覽器嘗試捲動至隱藏內容,以回應「在頁面中尋找」、「ScrollToTextFragment」和元素片段導覽時,會自動展開。這項設定不會變更。

不過,在使用獨家指令前,請先思考這對使用者有幫助或對使用者造成傷害。雖然使用專屬摺疊式可減少內容占用的視覺空間,但使用者可能必須開啟許多項目才能取得所有資訊。這可能會讓想同時查看多個項目的使用者感到不便。

如何設定標記樣式?

目前清單標記的樣式無法互通,因為有兩種不同的方法,一種是 Gecko 和 (目前的) Chromium 採用,另一種是 WebKit (先前與 Chromium 共用) 採用。

當地圖項目可以互通時,我們的目標是讓您更好地控制標記的樣式。

更多示範

最後,我們提供更多示範供您參考。這些都使用 ::details-content

UIKit 手風琴

示範

錄影

Chrome 131 中https://codepen.io/web-dot-dev/pen/rNXrJyQ的錄製內容

這個示範是根據 UIKit Accordion 建構而成。程式碼幾乎與先前分享的 Material UI 摺疊式選單相同。

部分開啟的揭露小工具

示範

錄影

Chrome 131 中 https://codepen.io/web-dot-dev/pen/PoMBQmW 錄製

這個示範內容包含部分開啟的揭露小工具,其內容已顯示在畫面上。為此,content-visibility 一律會設為 visibleheight使用 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 擬造動畫。