Monday, March 3, 2014

Simple Inline Tooltips

Attach custom tooltips to text (or any HTML element), inline and with almost no configuration whatsoever.



Getting Started

Include jQuery, inlinetooltip.1.0.js, and (optionally) inlinetooltip.1.0.css in your page's header:

    <script src="https://code.jquery.com/jquery-1.11.0.min.js"/>
    <link href="./inlinetooltip.1.0.css" rel="stylesheet"/>
    <script src="./inlinetooltip.1.0.js"/> 

Then, anywhere you want a tooltip, include it inline, like so:

    <span> 
        Tooltip trigger 
        <div class="iltt">Tooltip contents</div> 
    </span>



Example

What's that? You want nested tooltips with links and custom styles? Say no more. (In the live demo below, hover your mouse over the superscript "[1]", and then over the link that appears.)


Live Demo

"World domination is such an ugly phrase. I prefer to call it world optimisation." —Harry Potter[1]
From the often unintentionally hilarious Harry Potter fanfic, The Methods of Rationality
And when you're done with that, the review.
.


HTML
"World domination is such an ugly phrase. 
I prefer to call it world optimisation." 
—Harry Potter 

    <span> 
        <sup>[1]</sup> 
        <div class="iltt" style="width:280px;"> 
            From the often unintentionally hilarious Harry Potter fanfic, 
            <span> 
                <a href="http://hpmor.com/" target="_blank">
                <i>The Methods of Rationality</i></a>.
                <div class="iltt">And when you're done with that ...</div> 
            </span> 
        </div> 
    </span>



Motivation

I recently became fed up with the (lack of) ease-of-use and the glitchy and inconsistent behavior of the script I was previously using to display tooltips on my blog. I did some research on replacement options, but never really found anything I liked.

You can do some pretty interesting stuff with pure CSS, with compound selectors like parent:hover > child, and the :before and :after pseudo-selectors. But as far as I know, CSS can't, say, dynamically reposition tooltips based on complex criteria, or populate tooltips with the the results of an AJAX request.

Other tooltip libraries I found were inconvenient and not very intuitive. Most of them had lots of complicated markup and configuration, required inline JavaScript, or needed to have tooltip contents written as strings in separate JSON objects. Eventually I decided the only way I'd be able to find a tooltip script that worked just the way I wanted it to was if I wrote it myself, and the rest, as they say, is history.

Enjoy!



Source Code




5 comments:

  1. That's awesome!

    There's one problem though. Since the tooltips disappears when you move the mouse cursor out of the tooltop rectangle, right mouse click + Copy doesn't seem to copy anything. I'm using Mozilla Firefox v32.0.

    However, Ctrl + C works, but only when used with an active selection of the text inside the tooltip and when the cursor hasn't moved away from the tooltip.

    Is jquery-1.11.0.min.js the recommended version of jQuery to use with this code or is the latest stable version of jQuery (1.11.2) also an option?

    ReplyDelete
    Replies
    1. Unfortunately, there's no easy way to change the behavior you're seeing, as the default right click context menus aren't part of the webpage at all. Those menus are determined and controlled by your browser.

      In Chrome, moving the mouse cursor "outside" of a tooltip via a right-click menu doesn't trigger mouseout or mouseleave until the menu itself vanishes, which does allow you to, say, copy a link or text via right clicking. If you or your users have the option of using Chrome, that's one way around the problem.

      Firefox, on the other hand, does process mouseout and mouseleave events when you're mousing over a non-webpage context menu, which just really sucks. You might report this as a bug to the Firefox developers and cross your fingers.

      You can supersede the browser's default context menu by adding a 'contextmenu' eventlistener, which will allow you to display HTML content instead of a default context menu, but that's really outside the scope of this simple tooltip script.

      The version of jQuery shouldn't matter as long as the jQuery team hasn't made drastic non-backwards-compatible changes to their library. (I assume they haven't.) v1.11.0 was simply the latest stable release at the time I wrote this tooltip script.

      Delete
    2. Thanks a lot for your explanation!

      "In Chrome, moving the mouse cursor "outside" of a tooltip via a right-click menu doesn't trigger mouseout or mouseleave until the menu itself vanishes, which does allow you to, say, copy a link or text via right clicking. If you or your users have the option of using Chrome, that's one way around the problem."

      I'm not a native English user so I may have misunderstood that part. Here's a GIF that shows what I meant (I made it using a freeware program called GifCam): http://imgur.com/kA3LtYL (sorry about some of the UI text not being in English (that's Bulgarian by the way, if you're curious)).

      I'll consider reporting this to the Firefox Bugzilla bug tracker.

      Thanks for the clarification about the version of jQuery that's recommended for use with this code.

      Here are 2 more questions about your wonderful code:

      1. Can I put any HTML element inside the tooltips (not just text and hyperlinks), e.g. img, , etc.?

      2. On a side note, please have a look at the blue tooltip next to "← open these" on the following page: http://waitbutwhy.com/2015/01/artificial-intelligence-revolution-1.html (though those tooltips there behave in a different way — they appear on mouse click and disappear when you click somewhere on the page (that isn't the tooltip itself)). Is it possible to put sliders like that in your tooltips (i.e. for sliders to appear when the content of the tooltip exceeds certain limits) or make the tooltips behave in a similar way (mouseclick = appears, etc. like I already mentioned...)?

      Even if it may not be possible, I still find your code pretty awesome and I'm going to use it if you don't mind. :)

      Delete
    3. Yeah, that's what I thought you were talking about in Firefox. In Chrome, mousing over the default right-click context menu does not have that problem. You can right-click and select "Copy" successfully in Chrome.

      You can put anything you want inside the tooltips as long as the content isn't picky about its exact location in the DOM tree. Almost nothing is, just be aware that the initialization script un-nests all of the tooltip popups.

      You should be able to change the behavior of this script to match the behavior of the tooltips on the page you linked without much difficulty. Instead of binding mouseenter and mouseleave event handlers as this script does, you want to bind onclick event handlers.

      Each tooltip trigger will have an onclick event handler to show that particular tooltip's popup, and then the entire document will have an event handler to hide all the tooltip popups when you click anywhere else in the document. You can see an example of coding that behavior here: http://stackoverflow.com/questions/7566228/jquery-hide-if-clicked-outside-the-button

      Delete
  2. Thanks a lot for the explanation!

    I'm no programmer so I probably won't be able to change the code to use onclick event handlers, but I'll use the code as it is since I only mentioned the onclick behavior and the sliders because I was exploring those options in my mind. :) However, it's nice to know that it's indeed possible [for a person who knows how to code in JavaScript] to modify the code to achieve those effects.

    Cheers! :)

    ReplyDelete