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

發布日期:2024 年 11 月 6 日

從 Chrome 131 開始,您有更多選項可設定 <details><summary> 元素的樣式結構。現在建構揭露或手風琴式小工具時,可以使用這些元素。

特別是 Chrome 131 中導入的變更,可讓您在這些元素上使用 display 屬性,並新增 ::details-content 虛擬元素,為展開和收合的部分設定樣式。

Browser Support

  • Chrome: 131.
  • Edge: 131.
  • Firefox: 143.
  • Safari: 18.4.

Source

<details> 元素上設定 display

過去無法變更 <details> 元素的顯示類型,這項限制現已放寬,因此您可以在 <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 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 關鍵字才能運作。

加入先前分享的專屬手風琴示範,結果如下:

示範

錄影

在 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 虛擬元素則會產生動畫效果。