CSS-Plus
CSS-Plus
Play with web technologies

Create a Speech-Bubble Tooltip using CSS3 and jQuery

April 29, 2010
Attention: This article is old and the content is outdated. I've left the article here for historical purposes.
Create a Speech-Bubble Tooltip using CSS3 and jQuery

There are a couple of ways to create tooltips, but I decided that I wanted to try and create a very lightweight and good looking tooltip without using any images.

Alright, time to get started.

The HTML

This tooltip is going to work on any <a /> link that has a class of "sbtooltip" and contains a title attribute. <a class="sbtooltip" href="#" title="CSS3 and jQuery">Speech-Bubble Tooltip</a> This is a tooltip and should be very easy to implement, so very little HTML is needed for this to take effect.

The CSS

Before we get into the real CSS, the border property should be explained.

triangle-example

As you can see, you can form a triangle using borders. You can also create one of any size as long as you manipulate the border widths – Like we will be doing in the CSS for this tutorial. This is how the Speech-bubble's pointer will be created.

a.sbtooltip:hover {
    position: relative; /* Allows the tooltip to be absolutely positioned */
    z-index: 100;
}

/* Speech Bubble */
a.sbtooltip:before {
    background: rgb(224, 168, 38); /* For browsers that don't support gradients */
    background: -moz-linear-gradient(/* Firefox gradient */ 90deg, rgb(207, 141, 0) 44%, rgb(224, 168, 38) 72%);
    background: -webkit-gradient(
        /* Webkit gradient */ linear,
        left bottom,
        left top,
        color-stop(0.44, rgb(207, 141, 0)),
        color-stop(0.72, rgb(224, 168, 38))
    );
    color: #fff;
    content: attr(
        data-sbtooltip
    ); /* This takes the content of the attribute named "data-sbtooltip" and displays it within this element – We will use jQuery to take care of this to make sure that the document is still valid xHTML*/
    display: none; /* Hidden until hovered upon */

    /* Font, padding, top and right must change depending on the font size you are using on your web page */
    font: 12px sans-serif;
    padding: 5px 10px;
    position: absolute;
    top: 33px;
    right: 0;
    border-radius: 8px;
    box-shadow: 0 0 4px #999;
}

/* Triangle */
a.sbtooltip:after {
    border-width: 12px;
    border-style: solid;
    border-color: transparent transparent rgb(224, 168, 38) transparent;
    /* Forces this pseudo-element to appear on hover */
    content: "";
    display: none;
    /* Width and height could  be left out, but I prefer a less 'pointy' triangle */
    height: 2px;
    width: 2px;
    position: absolute;
    top: 10px;
    right: 10px;
}

/* Display on hover */
a.sbtooltip:hover:after,
a.sbtooltip:hover:before {
    /* The Speech-bubble tooltip and pointer will appear on hover */
    display: block;
}

Create a file called sbtooltip.css and type/paste the CSS into that file.

There you have it! If you add an attribute of "sbtooltip", containing a value, to an anchor link with a class of "sbtooltip" you will have a functional Speech-Bubble Tooltip!

A major problem with the 'sbtooltip' attribute is that the xHTML will not validate

validation-errors

Preferably, we would have the CSS 'content' property do the following: content: attr(title)

The only problem with this is the browser's native tooltip will appear over OUR tooltip. The whole reason we are creating a tooltip is to replace that one.

We are faced with a dilemma

Have the browser's native tooltip appear over the one we have just made, or have xHTML validation errors.

In order to correct this, we will need the help of the web developer's best friend. Javascript!

The jQuery javascript

I think it's going to be easiest to create a function to do our bidding. This will allow us the freedom to apply it to any element very easily so if you decide you want to change the class "sbtooltip" to something else within the CSS, it will be very easy to target a different element with the jQuery. Also, it will give you some insight into how to go about creating a function (If you don't already know).

// Function name
$.fn.sbTooltip = function() {
    // For each instance of this element
    return this.each(function() {
        // Add the new attribute with title's current value and then remove the title attribute
        $(this)
            .attr({ "data-sbtooltip": $(this).attr("title") })
            .removeAttr("title");
    });
};

This solves both of our problems. The document validates with xHTML strict.

validation-success

Create a file called jquery.sbtooltip.js and type/paste the function into that file. The function does nothing by itself; we will have to call the 'sbTooltip' function to an element, like this:

$(document).ready(function() {
    $("element").sbTooltip();
});

The CSS we have created only works on <a /> elements with a class of sbtooltip, so that is what we will be targeting.

Implementation

Before we go any further; if you have gotten to this point, and tried viewing this in Internet Explorer, you might have seen that it doesn't work properly and the native tooltip isn't showing up. To solve this problem we will have to use browser specific code to target everything that isn't Internet Explorer. I have saved the CSS as sbtooltip.css and the javascript as 'jquery.sbtooltip.js' like I suggested earlier. Place the following code within your <head> tag:

<!—jQuery loaded remotely -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js?ver=1.4.2"></script>
<!--[if !IE]><!-->
<link rel="stylesheet" type="text/css" href="css/sbtooltip.css" media="screen" />
<script type="text/javascript" src="js/jquery.sbtooltip.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $("a.sbtooltip").sbTooltip();
    });
</script>
<!--<![endif]-->

This code will load in every browser besides IE. You could view this tooltip as 'progressive enhancement' since IE users will still have their browser's native tooltip and they won't even know they are missing out on anything.

Extra information

  • The Speech-bubble's pointer looks good in Firefox and Chrome, decent in Safari, however it looks a bit jagged in Opera. An alternative to using the border could be to use an image or no speech-bubble pointer at all.
  • If you're <a /> hover state includes the property text-decoration: underline, the text within the tooltip will be underlined too - in Webkit browsers (Chrome and Safari). I hope you've learned something worthwhile during this tutorial.
Demo