藉助HTML5details,summary無JS實現各種互動效果

玄學醬發表於2018-06-21

瞭解HTML5 details, summary預設互動行為

<details>標籤在Chrome,Firefox等瀏覽器下預設是有展開收起行為的,例如下面HTML:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>這是摘要1<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>></span>這裡具體描述,標籤相對隨意,例如這裡使用的&lt;p&gt;標籤。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

結果UI表現為:

640?wx_fmt=png&wxfrom=5&wx_lazy=1

具體描述為:

  • 只顯示了<summary>標籤內容,而<p>預設隱藏了;

  • <summary>標籤前面出現了一個小三角;

小三角圖形的隱喻是:我是可點選的,點選我可能會出現寶箱。

OK,我們不妨就點選一下,結果如下圖:

640?wx_fmt=png&wxfrom=5&wx_lazy=1

具體描述為:

  • 原本隱藏的<p>標籤顯示出來了;

  • <summary>標籤前面的小三角方向朝下了;

此時我們再一次點選,<p>標籤內容又會隱藏收起,箭頭方向還原,如下圖:

0?wx_fmt=png

活脫脫一個天然的展開收起效果。

展開與收起是通過open屬性控制的

通過在<details>標籤上新增布林型別的open屬性,可以讓我們的詳情資訊預設就是展開狀態,如下HTML示意:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>這是摘要2<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>></span>這裡&lt;details&gt;標籤設定了HTML布林屬性open,因此,預設是展開狀態。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

結果如下截圖:

0?wx_fmt=png

如果我們使用JS指令碼手動移除這個open屬性,即使沒有點選行為的發生,我們內容也會收起。

<summary>如果預設

<summary>標籤如果預設,則<details>元素會在內部自動建立一個<summary>內容,預設的文案是“詳細資訊”。如下HTML程式碼:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>></span>如果&lt;summary&gt;預設,則會自動補上,文案是“詳細資訊”。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

結果如下截圖所示:

0?wx_fmt=png

您可以狠狠地點選這裡:HTML details,summary基本效果Demo。

details瀏覽器內建UI可以自定義

<details>標籤預設的小三角樣式有些簡陋,在實際應用的時候,往往不是我們希望的樣子,不要擔心,我們是可以對其進行自定義的。在Chrome等瀏覽器下使用::-webkit-details-marker,在Firefox瀏覽器下使用::-moz-list-bullet可以對小三角進行UI控制,例如改變顏色,改變大小,使用自定義的圖形代替,或者直接隱藏等,我們來看幾個簡單的案例。

小三角右側顯示同時顏色變淡

HTML程式碼如下:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>class</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“details-1”</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>這是示例1<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>></span>本案例展示對小三角UI重定義:包括顯示在右側,顏色減淡等。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

CSS如下:








.details-1 summary {    
   width: -moz-fit-content;








   width: fit-content;







   direction: rtl;
}
.details-1 ::-webkit-details-marker {    
   direction: ltr;







   color: gray;







   margin-left: .5ch;
}
.details-1 ::-moz-list-bullet {    
   direction: ltr;







   color: gray;







   margin-left: .5ch;
}




結果如下圖所示:

0?wx_fmt=png

當我們點選摘要標題升起的時候,表現為下圖(截自Firefox):

0?wx_fmt=png

眼見為實,您可以狠狠地點選這裡:HTML details小三角位置顏色改變Demo

而實際上實際開發的時候,對小三角UI更便捷的定製方法是:隱藏瀏覽器原生的小三角,然後藉助::before::after偽元素重新生成我們想要的UI效果,下面這個案例就將展示相關的處理。

隱藏瀏覽器原生的小三角並使用自定義三角替換

HTML結構還是類似的:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>class</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“details-2”</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>這是示例2<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>></span>本案例隱藏原生小三角,使用自定義小三角。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

CSS主要分為2部分,一部分是隱藏瀏覽器原生的小三角,另外一部分是使用偽元素生成自定義的三角效果。

首先看一下隱藏<details>標籤預設的小三角的CSS:


/* 隱藏預設三角 */
.details-2 ::-webkit-details-marker {    
   display: none;
}
.details-2 ::-moz-list-bullet {    
   font-size: 0;
}


可以看到Chrome瀏覽器和Firefox瀏覽器的小三角隱藏採用的是不同的策略。在Chrome瀏覽器下,我們可以直接設定display:none進行隱藏,但是這一招在Firefox瀏覽器下確實沒有效果的,即使設定display:none!important也是如此,根據我的測試,只有font-size:0能夠比較完美的隱藏。類似position:absolute;visibility:hidden這種常見的隱藏也是不行的,因為position:absolute無法生效。

然後是自定義小三角顯示的CSS,這裡採用的是::after偽元素模擬的:








/* 自定義的三角 */
.details-2 summary::after {    
   content: ``;








   position: absolute;







   width: 1em; height: 1em;







   margin: .2em 0 0 .5ch;







   background: url(./arrow-on.svg) no-repeat;







   background-size: 100% 100%;







   transition: transform .2s;
}
.details-2:not([open]) summary::after {    
   margin-top: .25em;







   transform: rotate(90deg);    
}




最終效果如下圖所示:

0?wx_fmt=png

收起時候:

0?wx_fmt=png

眼見為實,您可以狠狠地點選這裡:HTML details小三角自定義Demo。

最後有一點需要注意一下,就是如果<details>標籤內並沒有<summary>元素,則我們的對三角的自定義程式碼都是無效的,可以使用一個空的<summary>元素佔位,類似這樣:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>></span>內容。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

Chrome瀏覽器下點選時候outline輪廓等體驗處理

UI可以定製了,但是還有個不容忽視的體驗問題,那就是在Chrome瀏覽器下點選時候會出現outline輪廓,如下圖所示:

0?wx_fmt=png

在實際專案開發的時候,產品和設計一定會讓你把這個效果去掉的。以及,當我們<summary>元素點選較快的時候,文字會被選中,也不是我們想看到的。

阻止文字選中,我們可以:








summary {    
   -webkit-user-select: none;








   -moz-user-select: none;







   -ms-user-select: none;







   user-select: none;
}




對於outline輪廓,比較直接的做法是:


summary {    
   outline: 0;
}


但是這樣處理對無障礙訪問而是非常不友好的,那有沒有什麼辦法兼顧視覺體驗和無障礙訪問體驗呢?

我的做法是這樣子的:

利用<a>標籤的outline互動體驗

瀏覽器對<a>標籤元素的outline輪廓進行了專門的體驗優化處理,滑鼠點選的時候不顯示輪廓,鍵盤訪問時候顯示輪廓。於是我們可採用李代桃僵策略,讓<summary>元素的outline交給<a>元素,方法就是在<summary>中再內嵌一個<a>,同時通過tabindex屬性remove<summary>原本的可訪問性。HTML程式碼示意如下:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>tabindex</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“-1”</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“javascript:”</span></span>></span>這是示例<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>></span>點選無外框,鍵盤focus有。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

CSS如下:








summary {    
   user-select: none;








   outline: 0;
}
summary a {    
   color: inherit;
}




此時,在Chrome瀏覽器下,我們點選摘要資訊,沒有任何outline輪廓出現;但是當我們使用Tab鍵索引時候,可以看到下圖所示的輪廓效果:

0?wx_fmt=png

輪廓區域比原生的<summary>要小,但這無傷大雅,而且實際專案開發的時候,我們會去掉小箭頭,此時只要設定<a>標籤display:block,則輪廓就可以和<summary>保持一致了。

接下來,我們按下Space空格鍵,就會發現<details>元素內的內容資訊不斷的展開與收起:

0?wx_fmt=png

您可以狠狠地點選這裡:HTML5 summary outline輪廓a標籤處理Demo。

然後上面實現並不完美,相比原生的<summary>元素,EnterEnter鍵展開收起效果丟失了。這是因為HTML元素中如果多個focusable同時帶click瀏覽器行為元素巢狀的時候,點選裡面的元素,外部元素的瀏覽器行為是不會觸發的。類似的有<label>內嵌<a>標籤。

對於<a>標籤,其瀏覽器行為只能通過Enter鍵觸發,空格鍵是無效的;但是對於<summary>,Enter鍵和空格鍵都能觸發展開收起行為,這就是為什麼上面程式碼空格鍵有效,Enter鍵無效的原因。

如果想要同時支援Enter鍵展開與收起,可以對HTML如下處理:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>tabindex</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“-1”</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“javascript:”</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>onClick</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“this.parentNode.click();”</span></span>></span>這是示例<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>></span>點選無外框,鍵盤focus有。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>content</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

需要注意的是上面處理在<summary>自己額外繫結click事件時候可能會有double觸發的問題,此時,阻止<a>元素的冒泡即可。

JS捕獲鍵盤行為手動設定outline

這個方法不需要對HTML進行任何的改動,是通過CSS和JS配合對全域性的<summary>元素進行outline優化。

CSS如下:








summary {    
   user-select: none;








   outline: 0;
}
summary[focus] {    
   outline: 1px dotted;







   outline: 5px auto -webkit-focus-ring-color;
}




JS如下:








window.addEventListener(`keydown`, function () {    








   window.isKeyEvent = true;







   setTimeout(function () {







       window.isKeyEvent = false;







   }, 100);    







});













document.addEventListener(`focusin`, function (event) {







   var target = event.target;    if (target && target.tagName.toLowerCase() == `summary` && window.isKeyEvent == true) {







       target.setAttribute(`focus`, ``);







   }







});







document.addEventListener(`focusout`, function (event) {







   var eleFocusAll = document.querySelectorAll(`summary[focus]`);







   [].slice.call(eleFocusAll).forEach(function (summary) {







       summary.removeAttribute(`focus`);







   });







});




只要把上面的CSS和JS複製到頁面中,視覺體驗和互動體驗完美支援的<summary>元素outline效果就有了。

表現為,點選<summary>沒有任何outline,鍵盤focus時候出現,且和瀏覽器原生outline效果一模一樣,Space鍵和Enter鍵展開與收起訪問完全保留。

眼見為實,您可以狠狠的點選這裡:HTML5 summary outline輪廓JS優化Demo。

例如下圖就是鍵盤Tab鍵focus後回車後的效果:

0?wx_fmt=png

每每看到如此極致的使用者體驗處理,心情都大好。

原理:關鍵是全域性監聽keydown事件,如果有發生,則認為此100ms內的頁面focus行為均是鍵盤產生,從而有效區分是點選觸發的focus行為還是鍵盤觸發的focus行為,如果是鍵盤觸發,給<summary>元素手動增加outline效果。

基於details元素行為的各種互動效果案例

瞭解了<details>元素的點選互動行為;解決了UI定製難題;解決了outline的體驗問題,下面我們就可以付諸實踐,不借助任何JS來實現各種我們平常見到的互動效果。

“更多”展開與收起效果

實現最終效果如下gif:

0?wx_fmt=gif

因為“更多”元素是在底部,因此效果實現的要點的所有的內容資訊都放在<summary>元素內部,然後通過<details>元素的open屬性控制UI的變化。

HTML和CSS程式碼如下,其中,最核心部分已經紅色高亮:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>></span>據臺媒報導,大…青睞。<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>></span>  
  4.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>class</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“more”</span></span>></span>  
  5.             <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>></span>其他幾首歌曲…<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>p</span></span>></span>  
  6.         <span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>  
  7.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span>更多<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span>  
  8.     <span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span> <br><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>><br><br></span>::-webkit-details-marker {  
  9.     display: none;  
  10. }  
  11. ::-moz-list-bullet {  
  12.     font-size: 0;  
  13.     float: left;  
  14. }  
  15. .more {  
  16.     display: none;  
  17. }  
  18. [open] .more {  
  19.     display: block;  
  20. }  
  21. [open] summary a {  
  22.     font-size: 0;  
  23. }  
  24. [open] summary a::before {  
  25.     content: `收起`;  
  26.     font-size: 14px;  
  27. }</p>  

把“更多”對應的資訊放在.more元素內,然後通過[open]屬性選擇器控制器顯示,效果即達成。

您可以狠狠的點選這裡:HTML5 details/summary更多展開收起Demo。

無JS實現點選顯示懸浮選單,自定義下拉框等效果

效果如下gif:

0?wx_fmt=gif

沒有任何JS參與。HTML結構如下:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>我的訊息<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>   
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>class</span></span>=<span class=“value” style=“box-sizing: inherit;color: rgb(42, 161, 152);”><span class=“value” style=“box-sizing: inherit;”>“box”</span></span>></span>  
  4.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>我的回答<span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>sup</span></span>></span>12<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>sup</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span>  
  5.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>我的私信<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span>  
  6.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>未評價訂單<span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>sup</span></span>></span>2<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>sup</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span>  
  7.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>我的關注<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span>  
  8.     <span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

然後CSS讓.box元素絕對定位即可,顯示和隱藏<details>元素內建行為就搞定了。

您可以狠狠地點選這裡:HTML5 details/summary懸浮選單Demo。

Accordion多項摺疊效果

此效果常見於條目比較多的垂直導航欄,新聞條目等。

例如下面實現的效果:

0?wx_fmt=gif

這個更加簡單了,就是一堆<details>元素並排放置就可以了,如下HTML:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dt</span></span>></span>訂單中心<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dt</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>   
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>我的訂單<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span>  
  4.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>我的活動<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span>  
  5.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>評價曬單<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span>  
  6.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>購物助手<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  7.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dt</span></span>></span>關注中心<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dt</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>   
  8.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>關注的商品<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span>  
  9.     …<br><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>><br><br></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>></span>  
  10.     …<br><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

計算CSS沒有任何設定,效果也天然達成。

您可以狠狠地的點選這裡:HTML5 details/summary多列選單摺疊Demo。

帶slideUp/slideDown效果的多項摺疊選單

案例3中的展開項顯示的時候是非常生硬的突然顯示,實際上我們可以藉助一些選擇器技巧以及CSS3 transition屬性讓選單展開收起的時候是有動畫效果的,效果如下gif截圖:

0?wx_fmt=gif

此效果實現原理核心是[open]屬性選擇器,和加號+相鄰兄弟選擇器。

首先看下HTML,展開列表結構發生了變化,不是作為<details>的子元素,而是作為其相鄰兄弟元素存在,HTML示意:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>open</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”>    <<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>訂單中心<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dl</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>我的訂單<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>我的活動<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span>  
  4.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>評價曬單<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span>  
  5.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>></span><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span> <span class=“attribute” style=“box-sizing: inherit;color: rgb(181, 137, 0);”><span class=“attribute” style=“box-sizing: inherit;”>href</span></span>></span>購物助手<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>a</span></span>></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dd</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>dl</span></span>><br><br></span></p>  

上面<dl>定義列表就是展開收起的內容,其作為兄弟元素和<details>元素平起平坐,於是,我們就可以利用點選<summary>元素<details>元素的open屬性會變化的特性實現我們想要的動畫效果,CSS如下:








details + dl {    
   max-height: 0;








   transition: max-height .25s;







   overflow: hidden;
}

[open] + dl {    
   max-height: 100px;
}




藉助相鄰兄弟選擇器以及max-height任意元素slideUp/slideDown技術就可以效果達成。

您可以狠狠地點選這裡:HTML5 details/summary多列選單滑入滑出Demo。

多級巢狀的樹形選單互動效果

這裡的樹形選單效果實現也很簡單,多個<details>元素相互巢狀就可以,效果Gif如下:

0?wx_fmt=gif

HTML結構大致如下:

[xml] view plain copy

  1. <p style=“box-sizing: inherit;font-family: monospace, monospace;font-size: 1em;display: block;padding: 0.5em;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;line-height: 2em;”><span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  2.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>我的視訊<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  3.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  4.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>爆肝工程師的異世界狂想曲<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  5.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>tv1-720p.mp4<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>  
  6.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>tv2-720p.mp4<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>  
  7.         …        <br>        <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>tv10-720p.mp4<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>  
  8.     <span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  9.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  10.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>七大罪<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>summary</span></span>></span>  
  11.         <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>七大罪B站00合集.mp4<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>  
  12.     <span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span>  
  13.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>珍藏動漫網盤地址.txt<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>  
  14.     <span class=“tag” style=“box-sizing: inherit;”><<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>></span>我們的小美好.mp4<span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>div</span></span>><br></span><span class=“tag” style=“box-sizing: inherit;”></<span class=“title” style=“box-sizing: inherit;color: rgb(38, 139, 210);”><span class=“title” style=“box-sizing: inherit;”>details</span></span>></span></p>  

CSS的主要工作就是繪製選單前面的加號和減號圖形,例如我們可以藉助background線性漸變,具體可參見文章“CSS3 linear-gradient線性漸變實現虛線等簡單實用圖形”,相關CSS如下:








details {    
   padding-left: 20px;
}
summary::before {    
   content: ``;








   display: inline-block;







   width: 12px; height: 12px;







   border: 1px solid #999;







   background: linear-gradient(to right, #999, #999) no-repeat center, linear-gradient(to top, #999, #999) no-repeat center;







   background-size: 2px 10px, 10px 2px;







   vertical-align: -2px;







   margin-right: 6px;







   margin-left: -20px;
}

[open] > summary::before {    
   background: linear-gradient(to right, #999, #999) no-repeat center;







   background-size: 10px 2px;
}




效果即達成!

您可以狠狠地點選這裡:HTML5 details/summary樹形選單Demo。

如果只想要details/summary的語義不要行為

如果只想要<details>元素,<summary>元素的語義,但是並不需要點選展開收起的行為,該怎麼處理呢?

例如,某評論,或者某帖子有標題和正文,非常符合詳情-概要-內容的語義,但是希望是純展示的,點選時候不收起,可以這麼處理:

<summary>標籤設定tabindex="-1"讓鍵盤無法訪問;設定CSS:








summary {    
   outline: 0;








   pointer-events: none;
}




這樣就不能點,也不會有outline輪廓。

相容性以及Polyfill

0?wx_fmt=png

除了IE和Edge瀏覽器,大好河山一片綠,至少移動端可以用得比較開心。

如果想要在桌面Web網頁使用<details>元素的棒棒噠特性,我們可以對其進行Polyfill,可以參見此專案。

對鍵盤訪問,事件toggle都做了相容。

如果開發策略是對不支援的IE進行特異處理,則下面的JS判斷是否支援<details>元素的指令碼可能對你有用:


var isSupportDetails = `open` in document.createElement(`details`);

結束語麼麼噠

無JS實現的好處有:

  • 省了程式碼,載入快了;

  • 實現更簡單了,開發快了;

  • JS還沒載入互動也能進行,體驗好了;

  • 鍵盤無障礙和aria閱讀裝置無障礙天然支援,體驗檔次高了。

  • 可以跟同事炫,逼格上去了。

  • 好,感謝閱讀,行為倉促,歡迎糾錯。

本文作者:W3cplus_
本文釋出時間:2018年01月21日
本文來自雲棲社群合作伙伴CSDN,瞭解相關資訊可以關注csdn.net網站。


相關文章