20種簡單方式打造HTML details元素風格

本文將探討幾種簡單的方法來美化HTML中的<details>元素,這是一個非常實用的元素,用於在網頁上顯示和隱藏部分內容。

擁有一個不需JavaScript即可使用的簡單披露元素在HTML中非常方便,但<details>元素的默認樣式可能不適合所有人。幸運的是,改變這個元素的樣式相當容易。

下面目錄是一個使用<details>元素的例子。我們已經為它添加了一個簡單的邊框和一些內邊距。

Table of Contents

介紹詳情元素

以下是<details>元素的基本代码:

<details>
  <summary>Click me!</summary>
  <p>Peekaboo! Here's some hidden content!</p>
</details>

基本上,任何HTML内容都可以放置在<details>元素内部。<summary>元素提供了用户点击以显示更多内容的提示,并且它必须是<details>元素的第一个子元素。

这里是一个此代码的实时示例:

Click me!

躲猫猫!这里有一些隐藏的内容!

让我们看看所有可以使用CSS来增强我们的<details>元素外观的方法。

背景颜色、边框和内边距

A really simple way to enhance the look of the <details> element is to add some padding along with a border or some background colors.

添加边框

如上面的目录所示,一个简单的边框可以大大增强并定义<details>元素,再加上一些内边距和轻微的边框半径:

details {
  padding: 10px; 
  border: 5px solid #f7f7f7;
  border-radius: 3px;
}

这就是我们上面用来样式化我们的目录的简单代码。

添加一些背景颜色

让我们给我们的<details>元素添加一个背景颜色而不是边框:

details {
  padding: 10px;
  background-color: #e4eaef;
  border-radius: 5px;
}

结果显示在下面的Pen中。

背景颜色使元素更具定义性,内边距有助于在其中创建一些空间。

我们还可以给<summary>元素一个不同的背景颜色,以区别于其余内容,并改变其文本颜色。

summary {
  background-color: #2196F3;
  color: white;
  padding: 10px;
}

請注意,更改 `<summary>` 元素的文字顏色同時也會改變標記箭頭的顏色。這是因為標記實際上是附著在 `<summary>` 元素上,就像標記(如圓點)附著在列表項目上一樣。下面我們將看到如何分別對它們進行樣式設置。

標記的樣式設置

`<summary>` 元素被設置為 `display` 的 `list-item`。因此,它附帶的默認箭頭(▶)可以像HTML列表項目的默認標記一樣被修改。我們可以改變使用的字符,並獨立改變其顏色。

改變標記顏色

讓我們將默認標記設置為不同的顏色。為了好玩,我們也將標記的字體大小增加。這可以通過 `::marker` 偽元素來實現:

summary::marker {
  color: #e162bf;
  font-size: 1.2em;
}

結果如下所示。

這是一個很好的簡單解決方案,但不幸的是 `::marker` 在Safari中不支持,因此如果這是一個決定性的因素,請參考下面的其他選項。

改變標記間距

默認情況下,標記箭頭與摘要文本相當接近。其 `list-style-position` 被設置為 `inside`。如果我們將其更改為 `outside`,則可以通過添加一些左邊填充來在摘要文本和標記之間添加空間。我們還需要添加一些左邊距,以便三角形不會懸掛在容器外部:

summary {
  list-style-position: outside;
  margin-left: 30px;
  padding: 10px 10px 10px 20px;
  border-radius: 5px;
}

結果如下所示。

I’ve exaggerated the spacing between the arrow marker and the summary text just to make it obvious. Unfortunately, using list-style-position: outside; with the <summary> element doesn’t work in Safari. Fortunately, there are other options, as we’ll see below.

改變標記形狀

我們在 `

` 元素上的標記不一定要是三角形。我們可以將其替換為任何喜歡的字符:

summary {
  list-style-type: '⬇ ';
} 

注意,我們使用了 '⬇ '(箭頭旁邊有一個空格),這是上述嘗試的間距的替代方案。

現在我們有一個向下的箭頭而不是三角形。但是…那個向下的箭頭不會在 `

` 元素打開時改變。這是因為 `

` 元素有兩個狀態——`closed` 和 `open`——而我們只為 `closed` 狀態設置了標記樣式。因此,讓我們也為 `open` 狀態設置一個標記:
details[open] > summary {
  list-style-type: '⬆ ';
}

這次,我們使用了向上指的箭頭。這給我們帶來了如下所示的結果。

該死!Safari再次讓我們失望,因為它也不支持 `

` 元素上的 list-style-type。不過,不要絕望,因為我們將在下面查看更花哨的解決方案。

我們可以嘗試各種其他字符,如 + 和 –, ✓ 和 Χ 或 ✗, ⋁ 和 ⋀,甚至可以用其他字符如 ★ 或彩色水果如 🍏 🍌 🍓 🍋 和 🍐 來玩樂,但要記住,這些字符在所有系統上可能無法正常工作,所以要小心一點,並且再次提醒,list-style-type 在 Safari 中肯定不起作用。

為 summary 元素創建自定義標記

如上所述,儘管我們可以設定不同的預設標記字符,並賦予其顏色和字體大小等樣式,但這樣做可能會遇到問題。更好的選擇可能是完全移除標記,並創建一個完全自定義的替代方案。

移除自定義標記

與列表項目標記類似,我們可以完全移除標記:

summary  {
  list-style: none;
}

/* 唉,又是Safari */

summary::-webkit-details-marker {
  display: none;
}

標準的list-style: none在所有瀏覽器中都有效,除了…(你能猜到嗎?)…Safari。至少在這種情況下,有一個專有的-webkit-選項可用。

注意:另一種移除<summary>元素標記的方法是將<summary>元素的display值設為list-item以外的值,例如blockflex。這在所有瀏覽器中都有效,除了…(我甚至需要說嗎?)…Safari。

現在我們的元素沒有標記了。

沒有標記完全不會給出任何視覺提示表明此元素是可點擊的,因此僅此而已並不是一個好主意。

使用背景圖像作為標記

我們可以將圖像放置在背景上,如下所示:

summary {
  list-style: none;
  padding: 10px 10px 10px 40px;
  background: url(arrow.svg) no-repeat 14px 50%;
  background-size: 18px;
  font-weight: bold;
}

結果如下圖所示。

直接在<summary>元素上使用背景圖片的缺點是,當<details>元素展開時,我們無法旋轉它,因為CSS中無法直接對背景圖片設置動畫。(當然,我們可以使用另一張圖片來表示展開狀態,但仍無法對其進行動畫處理,這樣就少了很多樂趣。)因此,如果我們打算使用背景圖片,最好將其放置在一個能夠旋轉和/或動畫的元素上。

使用::after作為標記的背景圖片

讓我們將背景圖片放在::after偽元素內:

summary {
  display: flex;
}

summary::after {
  content: '';
  width: 18px;
  height: 10px;
  background: url('arrow.svg');
  background-size: cover;
  margin-left: .75em;
  transition: 0.2s;
}

details[open] > summary::after {
  transform: rotate(180deg);
}

以下是此代碼的實時演示。

我們在<summary>元素上使用了display: flex,以便於水平定位箭頭。

這種設置的好處是,我們可以為箭頭添加動畫。(動畫在Safari中似乎不起作用,但行為已足夠好,我對這個瀏覽器已經有些厭倦了!)

讓summary元素看起來像一個標籤

我們一直將<summary>元素設置為全寬,但其實不必如此。我們可以使其看起來更像一個標籤,只需進行以下簡單更改:

summary {
  display: inline-flex;
}

下面展示了一個示例。

限制details元素的寬度

到目前为止,我们在所有示例中使用的<details>元素都扩展到了其容器的全宽,因为它是一个块级元素。如果我们不希望它这么宽,可以给它设定不同的宽度,例如width: 50%;。或者,我们可以将其设置为内联显示,使其仅与内容一样宽:

details {
  display: inline-block;
}

点击下面的标签以显示<details>元素的较窄宽度。

尝试在上面的Pen中将display: inline-block更改为width: 50%

将标记箭头置于summary的远端

现在让我们做一些不同的事情,将标记箭头放在<summary>元素的右侧。因为我们一直使用display: flex,将箭头移动到最右侧只需在<summary>元素中添加justify-content: space-between

summary {
  display: flex;
  justify-content: space-between;
}

使用::after作为标记而不使用背景图像

我们还可以用其他方式使用::after而不使用实际图像。这里有一个仅使用::after和边框的例子:

summary::after {
  content: '';
  width: 0; 
  height: 0; 
  border-top: 10px solid #15171b;
  border-inline: 7px solid transparent;
  transition: 0.2s;
}

这里有一个实时演示。

现在我们有一个在关闭和打开状态之间旋转的箭头。我们还为<details>元素添加了一个漂亮的投影。

另一种不使用图像而使用::after的方法是在content属性中放置Unicode字符:

summary::after {
  content: "\25BC";
  transition: 0.2s;
}

此處將三角形(▼)設定為我們的標記,如此CodePen示範所示。

存在數以千計的Unicode符號,探索它們頗具趣味。每個符號都有一個代碼,例如U+25BCU+025BC。若要在content屬性中使用該代碼,只需取+後的字符,並將其置於content引號內,前綴以\content: "\25BC"。若開頭有一個或更多零,則可省略(例如,U+02248可變為"\02248""\2248")。

其他額外功能

截至目前,上述操作已十分充足,但仍有其他有趣之處可供探索,讓我們在此略試幾項。

<details>元素的懸停效果

我們可為<details>元素設定多種懸停效果。例如,可進行如下操作:

details {
  transition: 0.2s background linear;
}

details:hover {
  background: #dad3b1;
}

同時,讓我們也對<summary>open狀態下的文字顏色進行過渡處理:

details > summary {
  transition: color 1s;
}

details[open] > summary {
  color: #d9103e;
}

結果如下所示。

我們亦可僅對<summary>元素設定背景變化。

<details>元素的開啟與關閉動畫效果

哈哈,騙到你啦!看來無法對<details>元素的開啟和關閉進行動畫處理。根據MDN:

不幸的是,目前沒有內建的方法來動畫化開啟和關閉之間的過渡。

不過,我們可以通過動畫化<details>元素的內容來找點樂子。例如,我們可以設置內容在被揭示時淡入:

details article {
  opacity: 0;
}

details[open] article {
  animation: fadeIn .75s linear forwards;
}

@keyframes fadeIn {
 0% {
   opacity: 0;
 }
 100% {
   opacity: 1;
 }
} 

結果如下所示。

另一個技巧可能是讓內容滑入,就像這樣:

details {
  overflow: hidden;
}

details[open] article {
  animation: animateUp .5s linear forwards;
}

@keyframes animateUp {
  0% {
    opacity: 0;
    transform: translatey(100%);
  }
  100% {
    opacity: 1;
    transform: translatey(0);
  }
}

結果如下所示。

這有點俗氣,也許有點過頭,但還是值得一試。不幸的是,這些動畫只在第一次點擊元素時起作用(除非瀏覽器開發工具打開了,出於某種奇怪的原因!)。基本上,你需要JavaScript的介入來使效果能夠重複工作。

改變開啟和關閉狀態中的摘要內容

在上面的演示中,<select>無論<details>元素是開啟還是關閉,總是顯示相同的文字。但我們可以改變這一點。首先,讓我們保留當前的“點擊我”文字,但同時使用::after偽元素為每個狀態添加一些額外文字:

summary::after {
  content: " to show hidden content";
}

details[open] summary::after {
  content: " to hide extra content";
}

這給我們帶來了如下所示的結果。

改變摘要的光標

<details>元素的默認游標(或鼠標指針)有點奇怪。大部分情況下它是一個標準箭頭,而在懸停於<summary>文字上時則變為文字指針(或I型光標)。

為了好玩,我們將其更改為手形游標(或“指針”):

summary {
  cursor: pointer;
}

這樣設置後,當鼠標懸停在<summary>元素的任何位置時,游標都會變成一隻手,如下所示。

我們也可以將游標設置在<details>元素上,這樣會使整個<details>元素都強制顯示手形游標。不過,我更傾向於僅在應該點擊的位置保留手形游標。

更改可訪問性焦點樣式

如果我們通過鍵盤導航頁面,可以按Tab鍵到達<details>元素,然後通過按下回車鍵打開它。在焦點狀態下,<summary>元素有一個默認的外框。下圖展示了在不同瀏覽器中這看起來是怎樣的。

它們大致相同:基本上是一個簡單、深色(藍色或黑色)、約3px寬的實線外框。

我們可以為處於焦點狀態的<details>元素設置多種樣式,但這裡我們做一個簡單的示例來證明概念,將外框更改為紅色虛線:

summary:focus {outline: none;}
summary:focus-visible {outline: 3px dotted #ff0060;}
summary {padding: 10px;}

預設情況下,點擊<summary>元素時,焦點外框不會顯示。但如果我們更改焦點樣式,該樣式確實會顯示給非鍵盤用戶(即使用滑鼠點擊<details>元素時)。因此,在上面的代碼中,我們將outline設置為none,並使用focus-visible來設置樣式,這意味著焦點樣式僅對鍵盤用戶可見(對他們來說實際上有用)。

下圖展示了我們的新樣式。

這裡有一個即時演示。

我們可以利用這個功能玩出很多花樣,比如在<details>元素獲得焦點時使用動畫、背景顏色等。我將進一步的實驗留給你。

使用多個details元素如同手風琴列表

提案建議協調多個details元素,使得一個關閉時另一個打開。HTML規範甚至提出在多個<details>元素之間共用一個name屬性來實現此目的。

目前僅使用HTML和CSS無法實現此功能,但有一些巧妙的JavaScript示例可以做到這一點(例如這裡這裡這裡)。

使用CSS,我們最多只能將當前開啟的元素樣式與其他元素區分開來,使用上述介紹的一些技巧。

以下是一個簡單的示例:

details {
  background-color: #2196F3;
}

details[open] {
  background-color: #ce0e99;
}

在摘要內部樣式化標題

一些關心HTML結構的開發者喜歡在<summary>元素內放置一個標題元素。這是否有用尚有爭議,但默認渲染效果不佳,標題位於箭頭下方的一行。這可以通過將標題設置為display: inlinedisplay: inline-block來修復:

summary h2 {
  display: inline;
}

你可以在CodePen上查看此示例的演示。

結論

如上所述,有許多簡單方法可以美化 `<details>` 元素。設定邊框、內距和背景色非常容易,這些本身就能大大提升外觀。雖然一些方法能方便地樣式化默認標記,但考慮到 Forrest’s fruit company () 在樣式化標記方面存在眾多問題,最好避免使用該選項,轉而創建一個完全自定義的標記元素。(話雖如此,樣式化標記並不會 破壞 Safari 中的 `<details>` 元素。)

曾有人嘗試僅用 CSS 來動畫化 `<details>` 元素的開啟與關閉,但這些方法充其量只是權宜之計,因此不值得深入探究。如果你確實想要動畫化的開啟與關閉效果,則需要 JavaScript。

如需深入了解 `<details>` 元素,請查閱以下資料:

如果你有其他酷炫的 `<details>` 元素樣式方法,歡迎在 Twitter 上告訴我,我們或許會在這裡展示它們。

Source:
https://www.sitepoint.com/style-html-details-element/