如何使用纯CSS创建“工具提示尾巴”?

91
我刚刚发现了一个很棒的CSS技巧:
HTML:
<div>Cool Trick:<br />
    <div class="tooltiptail"></div>
</div>
<br />

<div>How do I get this effect with only CSS?<br />
    <div class="anothertail"></div>
</div>

CSS:

.tooltiptail {
    display: block;
    border-color: #ffffff #a0c7ff #ffffff #ffffff;
    border-style: solid;
    border-width: 20px;
    width: 0px;
    height: 0px;
}

.anothertail {
    background-image: url(http://static.jqueryfordesigners.com/demo/images/coda/bubble-tail2.png);
    display: block;
    height: 29px;
    width: 30px;

}

看看这个小提琴... http://jsfiddle.net/duZAx/1/ 这会创建一个类似箭头/三角形的效果,一个“工具提示尾巴”。这真是让我惊叹!我真的很想知道这是如何实现的?!
此外,有没有办法将这个CSS技巧扩展到以下效果...

        enter image description here

这是一个有趣的问题。
1. 可以只使用CSS来完成吗,而不使用阴影效果? 2. 可以使用阴影效果并且保持跨浏览器兼容性吗?

它必须在哪些浏览器中运行? - thirtydot
1
此时此刻,我并不是非常在意 :) 我只是想看看这是否可能!实际上,我会使用图像,但我对挑战很感兴趣。 - Hristo
1
这很简单但也很棒,Hristo找到了好东西! - Wesley Murch
我已经给了你一个投票,下次我会记得提到“+1”,好吗?这也是我最喜欢的问题 :) - Wesley Murch
@Madmartigan... 哈哈,对不起 :) 我很感激! - Hristo
显示剩余10条评论
6个回答

64

这里有一个带有box-shadow的例子,所有最新版本的浏览器都应该支持。

http://jsfiddle.net/MZXCj/1/

HTML:

<div id="toolTip">
    <p>i can haz css tooltip</p>
    <div id="tailShadow"></div>
    <div id="tail1"></div>
    <div id="tail2"></div>
</div>

CSS:

body {font-family:Helvetica,Arial,sans-serif;}

#toolTip {
    position:relative;
}

#toolTip p {
    padding:10px;
    background-color:#f9f9f9;
    border:solid 1px #a0c7ff;
    -moz-border-radius:5px;-ie-border-radius:5px;-webkit-border-radius:5px;-o-border-radius:5px;border-radius:5px;
}

#tailShadow {
    position:absolute;
    bottom:-8px;
    left:28px;
    width:0;height:0;
    border:solid 2px #fff;
    box-shadow:0 0 10px 1px #555;
}

#tail1 {
    position:absolute;
    bottom:-20px;
    left:20px;
    width:0;height:0;
    border-color:#a0c7ff transparent transparent transparent;
    border-width:10px;
    border-style:solid;
}

#tail2 {
    position:absolute;
    bottom:-18px;
    left:20px;
    width:0;height:0;
    border-color:#f9f9f9 transparent transparent transparent;
    border-width:10px;
    border-style:solid;
}

body {
  font-family: Helvetica, Arial, sans-serif;
}
#toolTip {
  position: relative;
}
#toolTip p {
  padding: 10px;
  background-color: #f9f9f9;
  border: solid 1px #a0c7ff;
  -moz-border-radius: 5px;
  -ie-border-radius: 5px;
  -webkit-border-radius: 5px;
  -o-border-radius: 5px;
  border-radius: 5px;
}
#tailShadow {
  position: absolute;
  bottom: -8px;
  left: 28px;
  width: 0;
  height: 0;
  border: solid 2px #fff;
  box-shadow: 0 0 10px 1px #555;
}
#tail1 {
  position: absolute;
  bottom: -20px;
  left: 20px;
  width: 0;
  height: 0;
  border-color: #a0c7ff transparent transparent transparent;
  border-width: 10px;
  border-style: solid;
}
#tail2 {
  position: absolute;
  bottom: -18px;
  left: 20px;
  width: 0;
  height: 0;
  border-color: #f9f9f9 transparent transparent transparent;
  border-width: 10px;
  border-style: solid;
}
<div id="toolTip">
  <p>i can haz css tooltip</p>
  <div id="tailShadow"></div>
  <div id="tail1"></div>
  <div id="tail2"></div>
</div>


1
太棒了!我原本也有一个相似的解决方案,但在做了那么多的解释之后,我变得有些懒了 :) +1 - BoltClock
@mdmullinax... 太棒了!等我恢复了点赞的权限,我会给你一个+1。 - Hristo
哇,太棒了!有一个小bug:工具提示的上方也能看到一点阴影。 - Iulius Curt
@iuliux...那个bug可以很容易地通过z-index修复 :) - Hristo

59

以下是对你的第一个问题的解释(我会把实际的CSS部分留给其他人,因为我有些懒——请投票支持你认为值得投票的答案!):

这创建了一个类似箭头/三角形的效果,即“工具提示尾巴”。这让我很惊讶!我真的很想知道这是如何工作的?!

  1. 当渲染具有不同边缘颜色但相同样式(在您的情况下为solid)的边框时,将每对相邻角之间的接缝线划分为对角线。这与此处所示的用于grooveridgeinsetoutset边框样式的图表非常相似。

    请注意,尽管所有浏览器的行为方式都相同,而且我能记得的时间长短,但这种行为在CSS2.1规范或CSS背景和边框模块中没有完全定义。后者有一个描述角落处的颜色和样式过渡的部分,并且描述似乎暗示对于角度半径为零的边框,实际呈现的线条是连接填充边缘的角和边框边缘的角的线条(对于等宽边框,结果是一条45度角的线),但规范仍然警告这可能并不总是正确的(特别是因为它甚至没有明确考虑边角半径为零的边框)。1

  2. 根据内容(原始W3C)框模型,40x40的区域由20像素的边界创建,其中内容尺寸定义为0x0。

  3. 将正方形通过连接其四个角的对角线划分为四个直角三角形,直角相遇于正方形的中点(见下图)。

  4. 顶部、底部和左侧边框为白色,以匹配.tooltiptail元素容器的背景,而右侧边框为蓝色阴影,以匹配工具提示的背景颜色:

    border-color: #ffffff #a0c7ff #ffffff #ffffff;
    
    结果是这样的,边框被标记出来,并使用我可靠的Line Tool添加了边界线:

    重新定位工具提示箭头只是简单地改变工具提示颜色的问题。例如,这将产生一个附在提示框底部的箭头:
    border-color: #a0c7ff #ffffff #ffffff #ffffff;
    

    jsFiddle 预览


    1 如果你是一个严格遵守标准的人,你可以将这一切视为 hack。


打字真快,我正要说同样的话... +1 - easwee
我显然很擅长读错问题。它甚至说“我还不担心阴影”。 - thirtydot
1
@BoltClock... 当我恢复了我的点赞特权,我会给你一个+1。 - Hristo
@BoltClock,这种行为在不同的浏览器中是否一致?根据w3c标准,这种行为有多“标准”? - Pacerier
@Pacerier:在任何规范中都没有定义将角落接缝呈对角线的具体行为。然而,这种行为在各种浏览器中是一致的,并且已经保持了很长时间的不变。我会在我的回答中澄清这一点。 - BoltClock

20

我用只有一个div元素实现了这个工具提示。

HTML:


HTML:

<div class="tooltip">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent augue justo, venenatis non tincidunt sit amet, suscipit eget ligula.</div>

CSS:

.tooltip{
    position: relative;
    border: 1px solid #73a7f0;
    width: 200px;
    margin-left: 20px;
    padding: 5px 14px;
    border-radius: 4px;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    box-shadow: 0px 0px 6px rgba(0, 0, 0, .7);
    -webkit-box-shadow: -0px 0px 6px rgba(0, 0, 0, .7);
    -moz-box-shadow: 0px 0px 6px rgba(0, 0, 0, .7);
}
.tooltip:before{
    content: ' ';
    display: block;
    position: absolute;
    left: -8px;
    top: 15px;
    width: 14px;
    height: 14px;
    border-color: #73a7f0;
    border-width: 1px;
    border-style: none none solid solid;
    background-color: #fff;
    box-shadow: -2px 2px 3.5px rgba(0, 0, 0, .5);
    -webkit-box-shadow: -2px 2px 3.5px rgba(0, 0, 0, .5);
    -moz-box-shadow: -2px 2px 3.5px rgba(0, 0, 0, .5);
    transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
}

演示

解释:

我有一个常规的带边框的div,就像其他示例一样。尾巴是CSS的简单组合:

  • 我使用伪选择器:before(:after也可以正常工作)
  • 我通过添加空格来强制显示尾巴。
  • 我将盒子从45度旋转以固定角落在工具提示的侧面
  • 大小和定位没有什么意外。
  • 我在我想要的两个边上添加了一个边框。
  • 最后我在外部边框上添加了阴影。

@Hristo 对于IE浏览器,我不是很清楚该怎么做,但我看到了一些文章:http://samuli.hakoniemi.net/cross-browser-rotation-transformation-with-css/ 但它看起来很困难...祝你好运! - Yoann
@DoubleYo:关于IE浏览器...如果我需要使其兼容IE,我会使用图片和条件样式表 :) - Hristo

11

没有阴影的工具提示

.abubble {
  position: relative;
  border: 1px solid #a0c7ff;
  width: 100px;
  height: 100px;
}
.ashadow {
  position: absolute;
  display: inline-block;
  background: transparent;
  width: 10px;
  height: 10px;
  left: 50px;
  top: 100px;
  -moz-box-shadow: 0px 10px 30px #000;
  -webkit-box-shadow: 0px 10px 30px #000;
  box-shadow: 0px 10px 30px #000;
}
.atail {
  position: absolute;
  display: inline-block;
  border-width: 20px;
  border-style: solid;
  border-color: #a0c7ff transparent transparent transparent;
  width: 0px;
  height: 0px;
  left: 30px;
  top: 100px;
}
.atail2 {
  position: relative;
  display: inline-block;
  border-width: 19px;
  border-style: solid;
  border-color: #fff transparent transparent transparent;
  width: 0px;
  height: 0px;
  left: -19px;
  top: -20px;
}
.anothertail {
  background-image: url(http://static.jqueryfordesigners.com/demo/images/coda/bubble-tail2.png);
  display: block;
  height: 29px;
  width: 30px;
}
<div>How do I get this effect with only CSS?
  <br />
  <div class="anothertail"></div>
</div>

<div class="abubble">
  <div class="atail">
    <div class="atail2">
    </div>
  </div>
</div>

演示代码


带阴影效果(在WebKit中看起来有点奇怪...我想得优化下):

.abubble {
  position: relative;
  border: 1px solid #a0c7ff;
  width: 100px;
  height: 100px;
  border-radius: 4px;
  -moz-border-radius: 4px;
  -webkit-border-radius: 4px;
}
.ashadow {
  position: absolute;
  display: inline-block;
  background: transparent;
  width: 10px;
  height: 10px;
  left: -5px;
  top: -16px;
  -moz-box-shadow: 0px 10px 20px #000;
  -webkit-box-shadow: 0px 10px 20px #000;
  box-shadow: 0px 10px 20px #000;
}
.atail {
  position: absolute;
  display: inline-block;
  border-width: 20px;
  border-style: solid;
  border-color: #a0c7ff transparent transparent transparent;
  width: 0px;
  height: 0px;
  left: 30px;
  top: 100px;
}
.atail2 {
  position: relative;
  display: inline-block;
  border-width: 19px;
  border-style: solid;
  border-color: #fff transparent transparent transparent;
  width: 0px;
  height: 0px;
  left: -19px;
  top: -20px;
}
.anothertail {
  background-image: url(http://static.jqueryfordesigners.com/demo/images/coda/bubble-tail2.png);
  display: block;
  height: 29px;
  width: 30px;
}
<div>How do I get this effect with only CSS?
  <br />
  <div class="anothertail"></div>
</div>

<div class="abubble">
  <div class="atail">
    <div class="ashadow"></div>
    <div class="atail2">
    </div>
  </div>
</div>

演示 1演示 2


@Archimedix...很酷 :) 现在我知道两种方法来做这件事,如果算上使用图片的话就是三种。要尝试一下阴影效果吗? - Hristo
@Archimedix... 看起来很棒!等我恢复了我的点赞特权,我会给你一个+1。 - Hristo
很好,和我的第二个解决方案一样 - 我也成功地解决了IE6中边框透明度的一些问题 - 但仍需要一个解决方案来显示箭头包装器在ie6中的边框。 - easwee

6

跨浏览器方法:

.tooltip {
  position:relative;
  padding:10px;
  border-bottom:1px solid #000;
  background:#ccc;
}

.arrow {
    background:transparent;
    display:inline-block;
    position:absolute;
    bottom:-20px;
    border-left:10px solid transparent;
    border-bottom:10px solid transparent;
    border-top:10px solid #000;
    border-right:10px solid transparent; 
}
.arrow i {
    display:inline-block;
    position:absolute;
    top:-10px;
    left:-9px;
    width:0;
    height:0;
    border-left:9px solid transparent;
    border-bottom:9px solid transparent;
    border-top:9px solid #ccc;
    border-right:9px solid transparent;
}
* html .arrow {
    border-bottom-color:white;
    border-left-color:white;
    border-right-color:white;
    filter: chroma(color=white);
}
* html .arrow i {
    border-bottom-color:white;
    border-left-color:white;
    border-right-color:white;
    filter: chroma(color=white);
}
<div class="tooltip">
    <span class="arrow"><i></i></span>
    Tooltip text that wants to be your friend.
</div>

这个可以在IE7及以上版本中使用(在IE6中也可以使用(filter: chroma(color=white);),但箭头周围不会显示黑色边框)。

IE6修复方法:

* html .arrow {
        border-bottom-color:white;
        border-left-color:white;
        border-right-color:white;
        filter: chroma(color=white);

}
* html .arrow i
        {
        border-bottom-color:white;
        border-left-color:white;
        border-right-color:white;
        filter: chroma(color=white);
        }

这将使IE6渲染的丑陋的黑色透明度变成您在chroma滤镜中指定的颜色(我选择了白色,因此它在背景中消失)。


CSS 3方法:

您可以使用CSS3旋转来完成,但无法在不支持CSS3的浏览器中实现:

.tooltip {
    position:relative;
    padding:10px;
    background:#ccc;
    border-bottom:1px solid #000;
}
.tooltip:before {
    content:"";
    display:block;
    width:10px;
    height:10px;
    position:absolute;
    bottom:-6px;
    border-left:1px solid #000;
    border-bottom:1px solid #000;
    background:#ccc;
    -webkit-transform: rotate(-45deg);
    -moz-transform: rotate(-45deg);
    transform: rotate(-45deg);
}

<div class="tooltip"> 
    Tooltip text that wants to be your friend.
</div>

@easwee... 太酷了!!!你能提供一些有关CSS3旋转的更多信息,教程和其他资源的链接吗? - Hristo
@hristo CSS3旋转只在IE9中受支持-因此您仍然需要关注IE7-8,它们仍然是需要编写代码的标准。但这是一个开始。 - easwee
在Linux x64上,也无法在Opera 11.01中运行。 - Iulius Curt
@iuliux - 是的,第一种方法只使用CSS3。看看第二种方法 - 它会更有效 :) - easwee
给那些点踩的人 - 如果你要点踩,请留下评论,这样我们可以知道你的原因。 - easwee
显示剩余5条评论

3
您可以利用CSS的:before和:after伪元素。例如,可以使用:before插入三角形,使用:after插入矩形。这两者的组合创建了一个气泡提示。
例如:
a[bubbletooltip]:before
{
    content: "";
    position: absolute;
    border-bottom: 21px solid #e0afe0;
    border-left: 21px solid transparent;
    border-right: 21px solid transparent;
    visibility: hidden;
    bottom: -20px;
    left: -12px;
}

a[bubbletooltip]:after
{
    position: absolute;
    content: attr(bubbletooltip);
    color: #FFF;
    font-weight:bold;
    bottom: -35px;
    left: -26px;
    white-space: nowrap;
    background: #e0afe0;
    padding: 5px 10px;
    -moz-border-radius: 6px;
    -webkit-border-radius:6px;
    -khtml-border-radius:6px;
    border-radius: 6px;
    visibility: hidden;
}

一个在线工具可以在http://www.careerbless.com/services/css/csstooltipcreator.php找到。

为什么使用自定义属性而不是比如说title - BoltClock
1
我认为aria-label是工具提示更适合的自定义属性。使用title会得到浏览器默认的工具提示渲染(对于有视力的用户来说)。 - rink.attendant.6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接