tooltip使用经验

1,963 阅读7分钟

tooltip使用经验

在改进【掘金Markdown增强器】脚本时,我想要实现和原本的组件里的一样的tooltip效果,就像这样:

掘金Markdown编辑器中的tooltip效果

于是我开始了漫长的调试之旅……

更新:2021年9月3日20:26:04

相关博客:油猴脚本——掘金Markdown格式适配器知识点记录 - 掘金
脚本地址:掘金Markdown格式适配器

1、如何实现一个 tooltip 组件效果

像这样的东西,大概率是已经有人提出了一些比较好的解决方案了,所以我索性先在网络上搜索了一番。我一开始是使用下面这篇博客中提到的代码:

参考:CSS 实现支持渐变的提示框(tooltips)-掘金(注意,这篇文章探讨的重点不是如何实现基本的tooltips,而是相关的进阶内容)

参考:文章中提到的tooltip实现代码-css-tips

这个思路还是挺清晰的,而且实现也比较巧妙。利用了 :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

参考:纯css怎么实现tooltip - web开发 - 亿速云

参考:用css实现tooltip效果

参考:几款好用的Tooltips 提示框插件_cc蒲公英的博客-CSDN博客_tips插件

2、在父元素设置了 overflow:hidden 时如何让子元素的 tooltip 不被遮挡

正当我把上面实现 tooltip 的代码在本地调试好,并把调试好的代码放到我的脚本中时,我突然发现压根没有效果!但是我通过控制台确确实实是看到了用伪类实现的 tooltip 元素啊,之后,经过一番折磨人的层层排查之后,我终于发现了原因:原来是包裹这个 tooltip 元素(准确地说应该是包裹 tooltip 所服务的那个元素)的父元素设置了 overflow:hidden ,而由 hover 触发而出现的 tooltip 元素恰好在这个父元素的外面,所以就被无情的遮挡(隐藏)住了。

父元素设置了 overflow:hidden 时导致子元素的 tooltip 被遮挡

父元素的这个 overflow:hidden 又不能随意干掉,一时间我没了法子……由此陷入了整夜的绝境……于是我又开始借助万能的互联网来寻求答案,但是我发现我所搜索到的答案很多都没有讲清楚这个事,绝大部分的中文搜索结果都是在说 EchartsHigncharts 的相关设置,要么就是牛头不对马嘴地再讲一些其他问题,后来搜到几篇中文博客是讲这个问题的,倒是有相关的解决方案,但是没有相关的代码验证。

更新:2021年8月31日15:38:52

参考:如何让子元素不受父元素 overflow:auto 的影响? - SegmentFault 思否

参考:如何让子元素不受父元素overflow的影响 - SegmentFault 思否

由于太晚了,所以昨晚就停在了这里,但是心里还是在意的,而今天又刚好是新学期第一堂课,还是不要太肝了。早上课时一直在想这个问题,但是都没有啥好方法,我还在一个前端交流群里发了问题,但是似乎没人感兴趣……上课回来后继续这个问题。终于在 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:afterposition: 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 */
}

具体效果如下:

tooltip的position设置为fixed

.content 元素可以用开发者工具设置为始终保持 hover 状态。

用开发者工具设置为始终保持 `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。可以看看张鑫旭的这两篇博客:

参考:CSS3 transform对普通元素的N多渲染影响 « 张鑫旭-鑫空间-鑫生活

参考:深入理解CSS中的层叠上下文和层叠顺序 « 张鑫旭-鑫空间-鑫生活

有关参考

更新:2021年8月31日14:45:34

【如何实现 tooltips 效果】

参考:CSS 实现支持渐变的提示框(tooltips)-掘金

参考:纯css怎么实现tooltip - web开发 - 亿速云

参考:用css实现tooltip效果

参考:用css实现tooltip效果 - 简书

参考:几款好用的Tooltips 提示框插件_cc蒲公英的博客-CSDN博客_tips插件

更新: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

参考:CSS3 transform对普通元素的N多渲染影响 « 张鑫旭-鑫空间-鑫生活

参考:深入理解CSS中的层叠上下文和层叠顺序 « 张鑫旭-鑫空间-鑫生活