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

我刚刚发现了一个简单的 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;
}
<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 技巧来创建如下效果:

enter image description here

这是一个有趣的问题。这是否可以只使用 CSS 来完成,暂时忽略阴影?


更新1

我想出了一个解决我最初问题的办法,这是小提琴..。

Http://jsfiddle.net/duzax/7/

超文本标示语言

<div style="position: relative;">Cool Trick:<br />
<div class="tooltiptail"></div>
<div class="tooltiptail2"></div>
</div>

CSS

.tooltiptail {
display: block;
border-color: #ffffff #a0c7ff #ffffff #ffffff;
border-style: solid;
border-width: 20px;
width: 0px;
height: 0px;
}
.tooltiptail2 {
display: block;
border-color: transparent #ffffff transparent transparent;
border-style: solid;
border-width: 18px;
width: 0px;
height: 0px;
position: relative;
left: 4px;
top: -38px;
}

现在,我如何准确地使用纯 CSS 模拟上面的小图片,包括阴影,并使其跨浏览器兼容?


更新2

下面是我在综合了以下答案后的解决方案。我还没有在多个浏览器上测试过,但是在 Chrome 中看起来很棒。

Http://jsfiddle.net/unsunghero97/mzxcj/688/

超文本标示语言

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

CSS

#toolTip {
background-color: #ffffff;
border: 1px solid #73a7f0;
width: 200px;
height: 100px;
margin-left: 32px;
position:relative;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
box-shadow: 0px 0px 8px -1px black;
-moz-box-shadow: 0px 0px 8px -1px black;
-webkit-box-shadow: 0px 0px 8px -1px black;
}


#toolTip p {
padding:10px;
}


#tailShadow {
background-color: transparent;
width: 4px;
height: 4px;
position: absolute;
top: 16px;
left: -8px;
z-index: -10;
box-shadow: 0px 0px 8px 1px black;
-moz-box-shadow: 0px 0px 8px 1px black;
-webkit-box-shadow: 0px 0px 8px 1px black;
}


#tail1 {
width: 0px;
height: 0px;
border: 10px solid;
border-color: transparent #73a7f0 transparent transparent;
position:absolute;
top: 8px;
left: -20px;
}


#tail2 {
width: 0px;
height: 0px;
border: 10px solid;
border-color: transparent #ffffff transparent transparent;
position:absolute;
left: -18px;
top: 8px;
}

59973 次浏览

Here's an explanation to answer your first question (I'll leave the actual CSS to others as I'm lazy — please upvote their answers which you think deserve the votes!):

This creates a little arrow/triangle-like effect, a "tooltip tail". This blows my mind! I'm really interested in knowing how this works?!

  1. When rendering a border with varying edge colors but the same style (in your case, solid), the seam dividing each pair of adjacent corners is a diagonal line. It's quite similar to what the diagram here depicts of the groove, ridge, inset and outset border styles.

    Note that while all browsers behave the same way and have done so for as long as I can remember, this behavior is not fully defined in either the CSS2.1 spec or the CSS Backgrounds and Borders module. The latter has a section describing color and style transitions at corners, and the description seems to imply that for borders with zero corner radii, the line that is rendered is in fact a line that joins the corner of the padding edge with the corner of the border edge (resulting in a 45-degree angled line for equal-width borders), but the spec still cautions that this may not always be the case (especially since it does not even account for borders with zero corner radii explicitly).1

  2. By the content (original W3C) box model, a 40x40 area is created out of the 20-pixel borders, with the content dimensions being defined as 0x0.

  3. Dividing a square with diagonal lines joining its four corners results in four right triangles whose right angles meet at the square's midpoint (see below).

  4. The top, bottom and left borders are white to match the background of the .tooltiptail element's container, while the right border is a shade of blue to match the background color of the tooltip:

    border-color: #ffffff #a0c7ff #ffffff #ffffff;
    

The result is this, with the borders labeled, and the border boundaries added using my trusty Line Tool:

Reorienting the tooltip tail is simply a matter of switching the tooltip color around. For example, this would yield a tail that's attached to the bottom of a tip:

border-color: #a0c7ff #ffffff #ffffff #ffffff;

jsFiddle preview


1 If you're a stickler for standards compliance, you may as well consider all this a hack.

Crossbrowser approach:

.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>

This one works from IE7+ (works in IE6 using (filter: chroma(color=white);) too but won't display the black border around the arrow).

IE6 fix:

* 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);
}

This will make the ugly black transparecy that is rendered by IE6 the color you specified in chroma filter (I did white so it disappears in background).


CSS 3 approach:

You could do it with CSS3 rotation, but will fail in non CSS3 compliant browsers:

.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>

Tooltip without shadow

.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>

Fiddle Demo


With Shadow (looks bit weird in WebKit... gotta optimize it I guess):

.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>

Demo 1, Demo 2

Here's an example with a box-shadow, all latest version browsers should support this

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>

I do this tooltip with only one div element.

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);
}

Demo

Explanation:

I have my normal div with border just like other example. The tail is a simple combination of CSS :

  • I use the pseudo selector :before (:after works fine too)
  • I force the content with a white space to make the tail visible.
  • I rotate my box from 45deg to fix the corner in the side of the tooltip
  • No surprise for the size and the positioning.
  • I add a border on the 2 sides i want.
  • And finally i add the shadows to the outside border.

You can make use of the :before and :after pseudo-elements of CSS. FOr instance, :before can be used to insert a triangle and :after to insert a rectangle. The combination of these two creates a bubble tool tip

Eg :

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;
}

An online tool is available at http://www.careerbless.com/services/css/csstooltipcreator.php