借助HTML5 details,summary无JS实现各种交互效果

简介:

了解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表现为:

具体描述为:

  • 只显示了<summary>标签内容,而<p>默认隐藏了;

  • <summary>标签前面出现了一个小三角;

小三角图形的隐喻是:我是可点击的,点击我可能会出现宝箱。

OK,我们不妨就点击一下,结果如下图:

具体描述为:

  • 原本隐藏的<p>标签显示出来了;

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

此时我们再一次点击,<p>标签内容又会隐藏收起,箭头方向还原,如下图:

活脱脱一个天然的展开收起效果。

展开与收起是通过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>  

结果如下截图:

如果我们使用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>  

结果如下截图所示:

您可以狠狠地点击这里: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如下:



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

  2.     width: fit-content;
  3.     direction: rtl;
    }
    .details-1 ::-webkit-details-marker {    
       direction: ltr;
  4.     color: gray;
  5.     margin-left: .5ch;
    }
    .details-1 ::-moz-list-bullet {    
       direction: ltr;
  6.     color: gray;
  7.     margin-left: .5ch;
    }

结果如下图所示:

当我们点击摘要标题升起的时候,表现为下图(截自Firefox):

眼见为实,您可以狠狠地点击这里: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伪元素模拟的:



   
   
  1. /* 自定义的三角 */
    .details-2 summary::after {    
       content: '';

  2.     position: absolute;
  3.     width: 1em; height: 1em;
  4.     margin: .2em 0 0 .5ch;
  5.     background: url(./arrow-on.svg) no-repeat;
  6.     background-size: 100% 100%;
  7.     transition: transform .2s;
    }
    .details-2 :not( [open]) summary ::after {    
       margin-top: .25em;
  8.     transform: rotate(90deg);    
    }

最终效果如下图所示:

收起时候:

眼见为实,您可以狠狠地点击这里: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轮廓,如下图所示:

在实际项目开发的时候,产品和设计一定会让你把这个效果去掉的。以及,当我们<summary>元素点击较快的时候,文本会被选中,也不是我们想看到的。

阻止文本选中,我们可以:



   
   
  1. summary {    
       -webkit-user-select: none;

  2.     -moz-user-select: none;
  3.     -ms-user-select: none;
  4.     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如下:



   
   
  1. summary {    
       user-select: none;

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

此时,在Chrome浏览器下,我们点击摘要信息,没有任何outline轮廓出现;但是当我们使用Tab键索引时候,可以看到下图所示的轮廓效果:

轮廓区域比原生的<summary>要小,但这无伤大雅,而且实际项目开发的时候,我们会去掉小箭头,此时只要设置<a>标签display:block,则轮廓就可以和<summary>保持一致了。

接下来,我们按下Space空格键,就会发现<details>元素内的内容信息不断的展开与收起:

您可以狠狠地点击这里:HTML5 summary outline轮廓a标签处理Demo。

然后上面实现并不完美,相比原生的<summary>元素,Enter回车键展开收起效果丢失了。这是因为HTML元素中如果多个focusable同时带click浏览器行为元素嵌套的时候,点击里面的元素,外部元素的浏览器行为是不会触发的。类似的有<label>内嵌<a>标签。

对于<a>标签,其浏览器行为只能通过回车键触发,空格键是无效的;但是对于<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 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如下:



   
   
  1. summary {    
       user-select: none;

  2.     outline: 0;
    }
    summary [focus] {    
       outline: 1px dotted;
  3.     outline: 5px auto -webkit-focus-ring-color;
    }

JS如下:



   
   
  1. window.addEventListener('keydown', function () {    

  2.    window.isKeyEvent = true;
  3.    setTimeout( function () {
  4.        window.isKeyEvent = false;
  5.    }, 100);    
  6. });
  7. document.addEventListener( 'focusin', function (event) {
  8.     var target = event.target;     if (target && target.tagName.toLowerCase() == 'summary' && window.isKeyEvent == true) {
  9.        target.setAttribute( 'focus', '');
  10.    }
  11. });
  12. document.addEventListener( 'focusout', function (event) {
  13.     var eleFocusAll = document.querySelectorAll( 'summary[focus]');
  14.    [].slice.call(eleFocusAll). forEach( function (summary) {
  15.        summary.removeAttribute( 'focus');
  16.    });
  17. });

只要把上面的CSS和JS复制到页面中,视觉体验和交互体验完美支持的<summary>元素outline效果就有了。

表现为,点击<summary>没有任何outline,键盘focus时候出现,且和浏览器原生outline效果一模一样,Space键和Enter键展开与收起访问完全保留。

眼见为实,您可以狠狠的点击这里:HTML5 summary outline轮廓JS优化Demo。

例如下图就是键盘Tab键focus后回车后的效果:

每每看到如此极致的用户体验处理,心情都大好。

原理:关键是全局监听keydown事件,如果有发生,则认为此100ms内的页面focus行为均是键盘产生,从而有效区分是点击触发的focus行为还是键盘触发的focus行为,如果是键盘触发,给<summary>元素手动增加outline效果。

基于details元素行为的各种交互效果案例

了解了<details>元素的点击交互行为;解决了UI定制难题;解决了outline的体验问题,下面我们就可以付诸实践,不借助任何JS来实现各种我们平常见到的交互效果。

“更多”展开与收起效果

实现最终效果如下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:

没有任何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多项折叠效果

此效果常见于条目比较多的垂直导航栏,新闻条目等。

例如下面实现的效果:

这个更加简单了,就是一堆<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截图:

此效果实现原理核心是[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如下:



   
   
  1. details + dl {    
       max-height: 0;

  2.     transition: max-height .25s;
  3.     overflow: hidden;
    }

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

借助相邻兄弟选择器以及max-height任意元素slideUp/slideDown技术就可以效果达成。

您可以狠狠地点击这里:HTML5 details/summary多列菜单滑入滑出Demo。

多级嵌套的树形菜单交互效果

这里的树形菜单效果实现也很简单,多个<details>元素相互嵌套就可以,效果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如下:



   
   
  1. details {    
       padding-left: 20px;
    }
    summary::before {    
       content: '';

  2.     display: inline-block;
  3.     width: 12px; height: 12px;
  4.     border: 1px solid #999;
  5.     background: linear-gradient(to right, #999, #999) no-repeat center, linear-gradient(to top, #999, #999) no-repeat center;
  6.     background-size: 2px 10px, 10px 2px;
  7.     vertical-align: -2px;
  8.     margin-right: 6px;
  9.     margin-left: -20px;
    }

    [open] > summary ::before {    
       background: linear-gradient(to right, #999, #999) no-repeat center;
  10.     background-size: 10px 2px;
    }

效果即达成!

您可以狠狠地点击这里:HTML5 details/summary树形菜单Demo。

如果只想要details/summary的语义不要行为

如果只想要<details>元素,<summary>元素的语义,但是并不需要点击展开收起的行为,该怎么处理呢?

例如,某评论,或者某帖子有标题和正文,非常符合详情-概要-内容的语义,但是希望是纯展示的,点击时候不收起,可以这么处理:

<summary>标签设置tabindex="-1"让键盘无法访问;设置CSS:



   
   
  1. summary {    
       outline: 0;

  2.     pointer-events: none;
    }

这样就不能点,也不会有outline轮廓。

兼容性以及Polyfill

除了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网站。
目录
相关文章
|
15天前
|
Web App开发 移动开发 HTML5
html5 + Three.js 3D风雪封印在棱镜中的梅花鹿动效源码
html5 + Three.js 3D风雪封印在棱镜中的梅花鹿动效源码。画面中心是悬浮于空的梅花鹿,其四周由白色线段组成了一个6边形将中心的梅花鹿包裹其中。四周漂浮的白雪随着多边形的转动而同步旋转。建议使用支持HTML5与css3效果较好的火狐(Firefox)或谷歌(Chrome)等浏览器预览本源码。
51 2
|
1月前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
130 1
|
1月前
|
前端开发 JavaScript 安全
HTML+CSS+JS密码灯登录表单
通过结合使用HTML、CSS和JavaScript,我们创建了一个带有密码强度指示器的登录表单。这不仅提高了用户体验,还帮助用户创建更安全的密码。希望本文的详细介绍和代码示例能帮助您在实际项目中实现类似功能,提升网站的安全性和用户友好性。
47 3
|
1月前
|
JavaScript
JS鼠标框选并删除HTML源码
这是一个js鼠标框选效果,可实现鼠标右击出现框选效果的功能。右击鼠标可拖拽框选元素,向下拖拽可实现删除效果,简单实用,欢迎下载
42 4
|
1月前
|
移动开发 HTML5
html5+three.js公路开车小游戏源码
html5公路开车小游戏是一款html5基于three.js制作的汽车开车小游戏源代码,在公路上开车网页小游戏源代码。
59 0
html5+three.js公路开车小游戏源码
|
1月前
|
JSON 移动开发 数据格式
html5+css3+js移动端带歌词音乐播放器代码
音乐播放器特效是一款html5+css3+js制作的手机移动端音乐播放器代码,带歌词显示。包括支持单曲循环,歌词显示,歌曲搜索,音量控制,列表循环等功能。利用json获取音乐歌单和歌词,基于html5 audio属性手机音乐播放器代码。
111 6
|
移动开发 JavaScript Android开发
|
JavaScript 前端开发 Java
HTML中的javascript交互
<p style="margin-top:0px; margin-bottom:1.1em; padding-top:0px; padding-bottom:0px; font-family:'microsoft yahei'; font-size:14px; line-height:26px"> <span style="">在Android开发中,越来越多的商业项目使用了Androi
1341 0