本文將探討幾種簡單的方法來美化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: '⬇ ';
}
注意,我們使用了 '⬇ '
(箭頭旁邊有一個空格),這是上述嘗試的間距的替代方案。
現在我們有一個向下的箭頭而不是三角形。但是…那個向下的箭頭不會在 `
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
以外的值,例如block
或flex
。這在所有瀏覽器中都有效,除了…(我甚至需要說嗎?)…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+25BC
或U+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: inline
或display: 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/