tooltip使用经验
在改进【掘金Markdown增强器】脚本时,我想要实现和原本的组件里的一样的tooltip效果,就像这样:
于是我开始了漫长的调试之旅……
更新:2021年9月3日20:26:04
1、如何实现一个 tooltip 组件效果
像这样的东西,大概率是已经有人提出了一些比较好的解决方案了,所以我索性先在网络上搜索了一番。我一开始是使用下面这篇博客中提到的代码:
参考:CSS 实现支持渐变的提示框(tooltips)-掘金(注意,这篇文章探讨的重点不是如何实现基本的tooltips,而是相关的进阶内容)
这个思路还是挺清晰的,而且实现也比较巧妙。利用了 :before 和 :after 两个伪元素选择器的特性,所以只用纯CSS就能完成 tooltips 效果。
<!-- HTML结构 -->
<div class="con">
<span class="css-tips" data-title="删除删除删除" data-title-dir="up">提示上</span>
</div>
/* 相应CSS样式 */
.con {
display: inline-block;
margin: 50px 80px;
}
.css-tips {
vertical-align: middle;
cursor: pointer;
border: #373c42 1px solid;
}
[data-title] {
position: relative;
overflow: visible;
}
.css-tips[data-title]:before,
.css-tips[data-title]:after {
display: block;
position: absolute;
z-index: 1;
left: 50%;
bottom: 100%;
transform: translate(-50%, -20px);
opacity: 0;
transition: .15s .15s;
color: #373c42;
visibility: hidden;
}
.css-tips[data-title]:before {
content: attr(data-title);
border-radius: 3px;
padding: 6px 10px;
line-height: 18px;
text-align: left;
background-color: #373c42;
color: #fff;
font-size: 12px;
font-style: normal;
white-space: nowrap;
}
.css-tips[data-title]:after {
content: '';
width: 0;
height: 0;
margin-bottom: -12px;
overflow: hidden;
border: 6px solid transparent;
border-top-color: currentColor;
}
.css-tips[data-title]:hover:before,
.css-tips[data-title]:hover:after {
visibility: visible;
opacity: 1;
}
我觉得上面这种方法是比较好的。当然还有其他的实现方法,有兴趣的可以到下面的链接中查看:
更新:2021年8月31日15:12:56
2、在父元素设置了 overflow:hidden 时如何让子元素的 tooltip 不被遮挡
正当我把上面实现 tooltip 的代码在本地调试好,并把调试好的代码放到我的脚本中时,我突然发现压根没有效果!但是我通过控制台确确实实是看到了用伪类实现的 tooltip 元素啊,之后,经过一番折磨人的层层排查之后,我终于发现了原因:原来是包裹这个 tooltip 元素(准确地说应该是包裹 tooltip 所服务的那个元素)的父元素设置了 overflow:hidden ,而由 hover 触发而出现的 tooltip 元素恰好在这个父元素的外面,所以就被无情的遮挡(隐藏)住了。
父元素的这个 overflow:hidden 又不能随意干掉,一时间我没了法子……由此陷入了整夜的绝境……于是我又开始借助万能的互联网来寻求答案,但是我发现我所搜索到的答案很多都没有讲清楚这个事,绝大部分的中文搜索结果都是在说 Echarts 或 Higncharts 的相关设置,要么就是牛头不对马嘴地再讲一些其他问题,后来搜到几篇中文博客是讲这个问题的,倒是有相关的解决方案,但是没有相关的代码验证。
更新:2021年8月31日15:38:52
由于太晚了,所以昨晚就停在了这里,但是心里还是在意的,而今天又刚好是新学期第一堂课,还是不要太肝了。早上课时一直在想这个问题,但是都没有啥好方法,我还在一个前端交流群里发了问题,但是似乎没人感兴趣……上课回来后继续这个问题。终于在 Stack Overflow (淦,看到这个 overflow 我都有点莫名焦躁了……)上找到了有人和我有同样的需求,于是顺着答主的思路,将他的代码放到本地浏览器调试,好家伙,终于算是给我整好了!
更新:2021年8月31日16:11:34
参考:css - Show tooltip over overflow:hidden - Stack Overflow
参考:Popping Out of Hidden Overflow | CSS-Tricks
参考:html - CSS Tooltip Div and overflow hidden - Stack Overflow
关键点有两处:
① 设置父元素 position: relative 。
② 设置子元素(tooltip所服务的那个元素)的 :before 和 :after 的 position: fixed。
下面是答主提供的代码的简化:
<!-- HTML结构 -->
<div class="tooltip-container">
<div class="content">鼠标移入</div>
<div class="tooltip">Super nice and awesome and cool and hot 1</div>
</div>
/* 相应CSS样式 */
.tooltip-container {
position: relative;
border: 1px black solid;
width: 200px;
height: 200px;
overflow: hidden; /* 父元素设置了 overflow: hidden; */
}
.content {
background-color: #9999FF;
width: 50px;
height: 50px;
}
.tooltip {
z-index: 1;
background-color: #FF9999;
display: none; /* 先设置了 tooltip 不显示 */
position: fixed; /* 设置tooltip 的 position 为 fixed */
transform: translate(50px, -50px);
white-space: nowrap;
}
.content:hover + .tooltip{
display: inline-block; /* 鼠标移入内容区时就显示 tooltip */
}
具体效果如下:
.content 元素可以用开发者工具设置为始终保持 hover 状态。
这不正是我想要的效果吗?接下来的事就是把我脚本里的相关代码套用这个方法即可(这里还是采用的伪元素实现的 tooltip)。
3、我的实现
<!-- HTML结构 -->
<div class="parent">
<div class="child" data-title="导入Markdown文档"></div>
</div>
/* 相应CSS样式 */
.parent {
width: 200px;
height: 100px;
background-color: #bfa;
margin: 100px auto;
position: relative; /* 关键,父元素 .parent 设置 position 为 relative */
}
.child {
width: 24px;
height: 24px;
background-color: rgb(253, 137, 214);
vertical-align: middle;
cursor: pointer;
position: relative;
top: 20px;
left: 100px;
overflow: visible;
}
.child:before,
.child:after {
display: block;
position: fixed;/* 关键 */
opacity: 0;
transition: .15s .15s;
visibility: hidden;
}
.child:before {
content: attr(data-title);
z-index: 2;
transform: translate(-53px, -36px);/* 关键,需要手动计算 */
border-radius: 5px;
padding: 5px 10px;
line-height: 16px;
text-align:center;
background-color: #333333;
color: #fff;
font-size: 12px;
font-style: normal;
white-space: nowrap;
}
.child:after {
content: '';
z-index: 1;
transform: translate(2px, -10px);/* 关键,需要手动计算 */
width: 0;
height: 0;
margin-bottom: -12px;
overflow: hidden;
border: 10px solid transparent;
border-top-color: #333333;
}
.child:hover:before,
.child:hover:after {
visibility: visible;
opacity: 1;
}
总体思路就是两者的结合,但是缺点是就是 :before 和 :after 的定位要手动计算,这样就会导致适配性比较差,但是好歹算是解决了我当前的问题。
最终效果:
关于具体为什么要用 postiton:fixed。可以看看张鑫旭的这两篇博客:
有关参考
更新:2021年8月31日14:45:34
【如何实现 tooltips 效果】
参考:CSS 实现支持渐变的提示框(tooltips)-掘金
更新:2021年8月31日15:38:52
【如何让子元素不受父元素 overflow 的影响】
参考:如何让子元素不受父元素 overflow:auto 的影响? - SegmentFault 思否
参考:如何让子元素不受父元素overflow的影响 - SegmentFault 思否
参考:css - Show tooltip over overflow:hidden - Stack Overflow
参考:Popping Out of Hidden Overflow | CSS-Tricks
参考:html - CSS Tooltip Div and overflow hidden - Stack Overflow
更新:2021年8月31日15:12:06
参考:CSS3伪类和伪元素的特性和区别 - JunpengZ - 博客园
更新:2021年8月31日18:20:28
参考:无障碍开发(三)之ARIA aria-***属性值_weixin_30510153的博客-CSDN博客
更新:2021年9月2日14:49:48