淺談 和

那一天我二十一歲,在我一輩子的黃金時代,我有好多奢望。我想愛,想吃,還想在一瞬間變整天上半明半暗的雲。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

使用 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;
}
複製代碼

注意:

  1. Chrome 默認看不見圖裏標的那個 #shadow root 的,須要在 Chrome 控制檯 Settings 中手動勾選 show user agent shadow DOM 選項,這個東西稱之爲影子樹(Shadow DOM),屬於 Web Component 的範疇。

  1. 在上圖的影子樹中,能夠看見一個具備 pseudo="-webkit-details-maker" 屬性的 div,這個屬性是未被規範化、因歷史緣由保留的一個屬性,summary 元素的那個箭頭就是用這個 div 實現的,咱們可使用 summary::-webkit-details-maker 控制這個元素的樣式,這也是上面去除 summary 默認箭頭的原理。Firefox 的設置於此稍有不一樣,接下來說到。

      再囉嗦一下,pseudo 是一個未被標準化的屬性。是由於早期,瀏覽器廠商爲了可以控制內部 DOM 結構(internal DOM structures)而引入的一個實驗特性,以後爲了兼容而獲得保留。Shadow DOM 標準出臺後,容許咱們用其餘方式,實現一樣的功能。

Gecko

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: "🐵";
}
複製代碼

參考連接

  1. The details and summary elements, by Tom Leadbetter.
  2. Primer CSS source code, by Github.

貢獻指北

感謝你花費寶貴的時間閱讀這篇文章。

若是你以爲這篇文章讓你的生活美好了一點點,歡迎給我鼓(diǎn)勵(zàn)😀。若是能在文章下面留下你寶貴的評論或意見是再合適不過的了,由於研究證實,參與討論比單純閱讀更能讓人對知識印象深入😉~。

(完)

相關文章
相關標籤/搜索