前言
在日常前端开发中,有时会有希望实现一些tooltip的特别样式,本文用以介绍部分相关概念和具体实现方法。
1.tooltip文本
tooltip文本由HTML的title属性实现,title属性定义的信息会在鼠标移动到元素上时显示出来。
兼容主流所有浏览器。
<div title="tooltip">Header</div>
但是用户会更倾向一些层次更清晰,样式更齐全的tooltip。
样式齐全,结构分明的tooltip会更加美观,阅读起来对用户也更加友好。
2.CSS实现
最开始遇到这个问题的时候,几乎所有的开发者的第一直觉就是通过CSS来实现这个需求。因为这样实现会更加简便,同时不会影响到你具体的业务逻辑代码。
2.1 :after 选择器
:after 选择器在被选元素的内容后面插入内容。
请使用 content 属性来指定要插入的内容。
<div title="tooltip">Header</div>
p:hover::after {
content:attr(title);
position: absolute;
z-index: 9999;
}
这种实现可以在对应的css中设置一些特殊的样式。需要注意以下几点:
- tooltip的position属性需要置为absolute,同时父元素的position属性需要置为relative,在通过绝对定位来将tooltip放在合适的区域。
- z-index属性需要设置高一些。
- tooltip文本设置在attribute的title中时,默认的tooltip也会渲染出来,建议直接换一个html的attribute来存放tooltip的content。
- before也可以,绝对定位已经无需关注dom元素的顺序。
2.2 通过隐藏dom实现
伪类可以实现一定的样式,但是也有许多局限性。
当我们还想给tooltip设置更加复杂的样式时,伪类对应的方案就不足以满足需求了。
首先,content属性是不支持HTML片段的注入,无法将结构层次放入tooltip,其次,样式的伪元素不支持在伪类中,比如::first-line,只支持对块元素的首行添加特殊的样式。
这时,我们就可以使用隐藏dom来实现。
<div class="tooltip-text">Header
<div class="tooltip" title="tooltip"></div>
</div>
// scss
.tooltip-text {
position: relative;
.tooltip {
position: absolute;
z-index: 9999;
visibility: hidden;
}
&:hover {
.tooltip {
transition: all 0.1s ease 0.5s;
visibility: visible;
}
}
}
核心原理和伪类实现基本相同,其中通过visibility来控制是否在一开始显示自定义的tooltip。
transition属性可以使hover的效果有一些小延迟,用户体验会更趋近于原生的tooltip。
dom实现的优点就是可以在dom内加入更多的dom节点,来实现各种层次和更花哨的样式。
但是在一定程度上污染了原来的HTML结构。
3.组件
具体的其实就是使用CSS实现,但将自定义tooltip作为组件的优点会很多。
通过js来动态创建对应的dom可以不破坏原本的HTML模板。之后修改HTML或是替换新的HTML都不会估计这一部分。
可复用性高,所有需要的地方都可以直接使用。
组件所需的接口:
container:HTMLElement;
HTML模板:string
对应的css直接在文件中引入即可。
具体实际就是动态生产一个dom,挂在对应container上,实现细节建议通过隐藏dom实现。
组件会使你的业务逻辑尽可能的解耦,你也可以不用过多关注具体实现。
总结
总的来说,实现的核心就是绝对定位来将用户自己的dom节点在hover时放在合适的位置,之后就可以发挥开发者所有的心思和创意来实现更具有结构,更花哨的tooltip了。