那一天我二十一歲,在我一輩子的黃金時代,我有好多奢望。我想愛,想吃,還想在一瞬間變整天上半明半暗的雲。css
——王小波《黃金時代》html
HTML5 引入的 <details>
元素好玩的一點是,用鼠標點點點,它包含的內容會在顯示與隱藏之間切換。html5
代碼就很是簡單啦,這樣的git
<details>
<div>你好啊</div>
</details>
複製代碼
若是調出控制檯的話,會能看到實現顯隱的細節:github
<details>
元素有一個 open
布爾值屬性,默認它包含的內容(除了 summary
)是隱藏的,加了這個屬性以後,內容就顯示出來了。web
<summary>
老是和 <detail>
配合使用。其實,上面代碼裏,雖然咱們沒有在 <details>
包含 <summary>
,可是 ,<details>
會有一個缺省的 summary
,也就是說:瀏覽器
<details></details>
<!-- 等同於(中文環境下) -->
<details>
<summary>詳細信息</summary>
</details>
<!-- 若是咱們手動設置 `<summary>`,就會覆蓋掉缺省的 -->
<details>
<summary>一首小詩</summary>
</details>
複製代碼
舉一個完整的小例子:dom
<details open>
<summary>Overview</summary>
<ol>
<li>Cash on hand: $500.00</li>
<li>Current invoice: $75.30</li>
<li>Due date: 5/6/19</li>
</ol>
</details>
複製代碼
<details>
中除了 <summary>
元素是始終顯示的外,其餘部分都受到 open
屬性的影響,產生對應的顯隱效果。ide
一種使用場景是摺疊面板:spa
還有一種就是下拉框了。
以下圖所示,Github 的下拉框就是使用 <details>
和 <summary>
實現的。
本文不介紹實現上面兩種場景所可能須要的 JS 邏輯,在這裏只是提供一種實現思路。固然了,在使用這兩個元素前,須要知道怎麼給它們應用樣式,這樣纔算是真正的物盡其用。
首當其衝的就是去除那個箭頭。
默認 <summary>
元素右側會有一個箭頭來只是當前內容展開、收起狀態的。一般寫網頁時,都須要將這個箭頭樣式去掉,替換成咱們設計所須要的那個樣子。
去掉這個箭頭咱們要從渲染引擎出發:Webkit 和 Gecko。
使用 Webkit 引擎的主要瀏覽器包括:Chrome 和 Safair。咱們以 Chrome 爲例,Safair 於此相似。
下面是箭頭部分的樣式,它是用僞元素 ::-webkit-details-marker
模擬的:
summary::-webkit-details-marker {
display: inline-block;
width: 0.66em;
height: 0.66em;
margin-inline-end: 0.4em;
}
複製代碼
感受樣式,去掉箭頭的方式超簡單,就是將僞元素設置成 display: none
就能夠了。
summary::-webkit-details-marker {
display: none;
}
複製代碼
注意:
- Chrome 默認看不見圖裏標的那個
#shadow root
的,須要在 Chrome 控制檯 Settings 中手動勾選 show user agent shadow DOM 選項,這個東西稱之爲影子樹(Shadow DOM),屬於 Web Component 的範疇。![]()
- 在上圖的影子樹中,能夠看見一個具備
pseudo="-webkit-details-maker"
屬性的 div,這個屬性是未被規範化、因歷史緣由保留的一個屬性,summary
元素的那個箭頭就是用這個 div 實現的,咱們可使用summary::-webkit-details-maker
控制這個元素的樣式,這也是上面去除summary
默認箭頭的原理。Firefox 的設置於此稍有不一樣,接下來說到。再囉嗦一下,
pseudo
是一個未被標準化的屬性。是由於早期,瀏覽器廠商爲了可以控制內部 DOM 結構(internal DOM structures)而引入的一個實驗特性,以後爲了兼容而獲得保留。Shadow DOM 標準出臺後,容許咱們用其餘方式,實現一樣的功能。
Firefox 使用的是 Gecko 引擎,與 Webkit 不一樣。若是咱們調出 Firefox 的控制檯,查看 summary
使用的用戶代理就會發現,它是直接將 summary 元素設置成 list-item 元素,展現那個箭頭的。
details > summary:first-of-type {
display: list-item;
list-style: disclosure-closed inside;
}
details[open] > summary:first-of-type {
list-style-type: disclosure-open;
}
複製代碼
所以重置樣式、把箭頭去掉時,有兩種方式:
// 方式1、將 `summary` 元素的 `list-style` 屬性設置爲 `none`
summary {
list-style: none;
}
// 方式2、重置 `summary` 元素的 `display` 值,好比 `block`、`inline-block` 之類的
// 不過丟失些許通用性,兼有一些破壞性
// 所以仍是推薦第一種方式
summary {
display: inline-block;
}
複製代碼
// 代碼來源:https://github.com/primer/css/blob/v12.4.0/src/buttons/button.scss#L205
.details-reset {
// Remove marker added by the display: list-item browser default
> summary { list-style: none; }
// Remove marker added by details polyfill
> summary::before { display: none; }
// Remove marker added by Chrome
> summary::-webkit-details-marker { display: none; }
}
複製代碼
上面的最終代碼是從 Primer CSS 源碼中截取的,多了一個去除 Details Polyfill 的樣式代碼。
如今咱們寫個簡單的自定義樣式代碼吧。
// See:https://github.com/primer/css/blob/v12.4.0/src/buttons/button.scss#L205
details {
// Remove marker added by the display: list-item browser default
> summary { list-style: none; }
// Remove marker added by details polyfill
> summary::before { display: none; }
// Remove marker added by Chrome
> summary::-webkit-details-marker { display: none; }
}
// custom style
summary:after {
content: "🙈";
float: left;
}
details[open] summary:after {
content: "🐵";
}
複製代碼
感謝你花費寶貴的時間閱讀這篇文章。
若是你以爲這篇文章讓你的生活美好了一點點,歡迎給我鼓(diǎn)勵(zàn)😀。若是能在文章下面留下你寶貴的評論或意見是再合適不過的了,由於研究證實,參與討論比單純閱讀更能讓人對知識印象深入😉~。
(完)