How can I create a "tooltip tail" using pure CSS?
Asked Answered
F

6

91

I just came across a neat CSS trick:

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;

}

Check out the fiddle... http://jsfiddle.net/duZAx/1/

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

Further, is there a way to extend this CSS trick to create an effect as follows...

        enter image description here

This is an interesting problem.

  1. Can this be done using only CSS, without the shadow?
  2. Can this be done with the shadow and having it cross-browser compatible?
Fransen answered 11/4, 2011 at 14:46 Comment(5)
Should be doable if using layered elements and pixel-perfect positioning for the outline. With or without the shadow ?Jodeejodhpur
What's up with the little bitty white square on there in Chrome?Braxy
@drachenstern... what exactly are you referring to? I think the little white square has to do with the shadow on the little arrow.Fransen
It really doesn't look great in Chrome... All css3 shadows are box-shadows, so they're squared. A triangle square is impossible and that's what your original image does have. A sort of related article is blogs.sitepoint.com/pure-css3-ribbonsMesdemoiselles
@Rudie... the original image has a small circular shadow, if that's what you're referring to, and I'm not that worried about making it look exactly like that. I just wanted to have the general shadow working so box-shadow is enough for my case. Also, if I really wanted to make it look like the image itself, I can use another element, make it like 1px by 1px, and give it a bigger box shadow and spread it out to make it look like a circle :)Fransen
O
64

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>
Oftentimes answered 11/4, 2011 at 15:55 Comment(2)
wow, great! A small bug: the shadow is also visible a little in the upper side of the tooltipBanas
@iuliux... that bug can be easily fixed with z-index :)Fransen
T
60

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.

Tillett answered 11/4, 2011 at 14:52 Comment(3)
Well, I clearly suck at reading questions. It even said "I'm not worried about the shadow yet".Nothing
@BoltClock, Are the behaviors consistent across browsers? And how standard is this behavior according to w3c?Dynast
@Pacerier: The specific behavior of rendering the corner seam as a diagonal line is not defined in any spec. The behavior is consistent across browsers and has remained unchanged for a long time, however. I'll clarify this in my answer.Tillett
C
20

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.
Contagium answered 12/4, 2011 at 9:34 Comment(2)
@Fransen For IE I don't realy know how to do, but a see some article : samuli.hakoniemi.net/… But its look to be dificult... "Bon courage !"Contagium
@DoubleYo: In regards to IE... if I need to make this IE compatible, I'll just use images and a conditional stylesheet :)Fransen
J
11

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

Jodeejodhpur answered 11/4, 2011 at 15:47 Comment(3)
@Archimedix... cool :) now I know 2 ways to do this, well 3 if you count using images. care to go for the shadow effect?Fransen
@Archimedix... looks great! when I get my upvoting privileges back, I'll give you a +1Fransen
Nice same as my second solution - I also managed to fix some of border transparency in IE6 - still need a solution for the wrapper of the arrow to display the border in ie6.Clementia
C
6

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>
Clementia answered 11/4, 2011 at 15:15 Comment(10)
@easwee... cool!!! Would you be able to provide some more info on css3 rotation, links to tutorials and other resources?Fransen
@hristo - there is a dx filter for rotation in IE - but problem is that it takes only 4 values - msdn.microsoft.com/en-us/library/ms532918%28v=vs.85%29.aspxClementia
@easwee... I'm not too worried about IE, especially IE 6. Thanks for pointing that out. Any IE bugs can easily be overcome with a conditional :)Fransen
@hristo css3 rotation is supported in IE9 only - so you still have to take care for ie7-8 which are still a standard to code for. But it's a start.Clementia
@easwee... awesome. If I ever need to do this and make it IE-compatible, I would use an image and a conditional stylesheet :) Would you be able to provide some more info on css3 rotation, links to tutorials and other resources?Fransen
Dunno I wrote this out of head - just consult the w3c reccomandation - best way to understand something is to read it's definition. Atleast for me. w3.org/TR/css3-2d-transforms/#transform-functionsClementia
also fails in Opera 11.01 on Linux x64Banas
@iuliux - Yeah first approach is CSS3 only. Check the second approach - it will work better :)Clementia
To the one who downvoted this - leave a comment if you are downvoting so we can know what your reasons are.Clementia
i once made one a bit more sophisticated version like yours: jsfiddle.net/flyingsheep/NKwg9Giraud
D
3

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

Diaper answered 5/2, 2013 at 18:42 Comment(2)
Why a custom attribute and not, say, title?Tillett
I would say that aria-label is a more appropriate custom attribute for a tooltip. With title, you also get the browser's default tooltip rendering (for sighted users anyways).Concinnate

© 2022 - 2024 — McMap. All rights reserved.