本文利用的是HTML5 details, summary
首先
一、了解HTML5 details, summary默认交互行为
<details> 标签在Chrome,Firefox等浏览器下默认是有展开收起行为的,例如下面HTML:
<details> <summary>这是摘要1</summary> <p>这里具体描述,标签相对随意,例如这里使用的<p>标签。</p> </details>
结果UI表现为:
具体描述为:
1、只显示了<summary>标签内容,而<p>默认隐藏了;
2、<summary>标签前面出现了一个小三角;
小三角图形的隐喻是:我是可点击的,点击我可能会出现宝箱。
OK,我们不妨就点击一下,结果如下图:
具体描述为:
原本隐藏的<p>标签显示出来了;
<summary>标签前面的小三角方向朝下了;
此时我们再一次点击,<p>标签内容又会隐藏收起,箭头方向还原,如下图:
活脱脱一个天然的展开收起效果。
展开与收起是通过open属性控制的
通过在<details>标签上添加布尔类型的open属性,可以让我们的详情信息默认就是展开状态,如下HTML示意:
<details open> <summary>这是摘要2</summary> <content>这里<details>标签设置了HTML布尔属性open,因此,默认是展开状态。</content> </details>
结果如下截图:
如果我们使用JS脚本手动移除这个open属性,即使没有点击行为的发生,我们内容也会收起。
<summary>如果缺省
<summary>
标签如果缺省,则<details>
元素会在内部自动创建一个<summary>
内容,默认的文案是“详细信息”。如下HTML代码:
<details open> <p>如果<summary>缺省,则会自动补上,文案是“详细信息”。</p> </details>
结果如下截图所示:
二、details浏览器内置UI可以自定义
<details>标签默认的小三角样式有些简陋,在实际应用的时候,往往不是我们希望的样子,不要担心,我们是可以对其进行自定义的。在Chrome等浏览器下使用::-webkit-details-marker,在Firefox浏览器下使用::-moz-list-bullet可以对小三角进行UI控制,例如改变颜色,改变大小,使用自定义的图形代替,或者直接隐藏等,我们来看几个简单的案例。
案例1:小三角右侧显示同时颜色变淡
HTML代码如下:
<details class="details-1" open> <summary>这是示例1</summary> <content>本案例展示对小三角UI重定义:包括显示在右侧,颜色减淡等。</content> </details>
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; }
结果如下图所示:
当我们点击摘要标题升起的时候,表现为下图(截自Firefox):
而实际上实际开发的时候,对小三角UI更便捷的定制方法是:隐藏浏览器原生的小三角,然后借助::before或::after伪元素重新生成我们想要的UI效果,下面这个案例就将展示相关的处理。
案例2:隐藏浏览器原生的小三角并使用自定义三角替换
HTML结构还是类似的:
<details class="details-2" open> <summary>这是示例2</summary> <content>本案例隐藏原生小三角,使用自定义小三角。</content> </details>
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); }
最终效果如下图所示:
收起时候:
最后有一点需要注意一下,就是如果<details>标签内并没有<summary>元素,则我们的对三角的自定义代码都是无效的,可以使用一个空的<summary>元素占位,类似这样:
<details> <summary></summary> <content>内容。</content> </details>
三、Chrome浏览器下点击时候outline轮廓等体验处理
UI可以定制了,但是还有个不容忽视的体验问题,那就是在Chrome浏览器下点击时候会出现outline轮廓,如下图所示:
在实际项目开发的时候,产品和设计一定会让你把这个效果去掉的。以及,当我们<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轮廓进行了专门的体验优化处理,鼠标点击的时候不显示轮廓,键盘访问时候显示轮廓。于是我们可