Tippy.js

A lightweight, pure JavaScript tooltip library

Features

Hover your cursor over the buttons to see Tippy in action!Tap the buttons to see Tippy in action!

important_devices Browser support

Most browsers from 2012 onwards (IE10+). As of early 2017, it should support 95% of users (caniuse.com); depending on your target audience it could be higher or lower. Tippy gracefully degrades on older browsers (and with JavaScript disabled) by using the browser's default title tooltip.

Unsupported browsers

Old IE and Opera Mini should not throw errors but others might

Browsers Year last version released User share
IE <= 9 2011 0.6%
Opera Mini 2015 3%
Firefox <= 33 2014 0.3%
Safari <= 5.1 2011 0.1%
Opera <= 12.1 2011 0.1%
Potentially unsupported/untracked, very old mobile browsers N/A 1-2%

tag_facesGetting started

CSS

Place the tippy.css stylesheet in your document's head.

<link rel="stylesheet" href="css/tippy.css">

JS

Include the tippy.js file in your document before your own scripts:

<script src="js/tippy.js"></script>

If you're using Node/Webpack, you can import the Tippy module:

import Tippy from './js/tippy'

Tippy is dependent on Popper.js - an awesome positioning library that takes the headache out of positioning all the tooltips nicely. The production file comes bundled with it.


buildCreating a tooltip

First, give an element a title attribute containing what you want the tooltip to say.

<button class="btn tippy" title="I'm a tooltip!">Text</button>

Then, to give it a Tippy tooltip, create a new Tippy instance by passing in a CSS selector.

new Tippy('.tippy')

Result:

You can also directly pass in a DOM element:

new Tippy(document.querySelector('#myElement'))

Elements without a title attribute or an HTML template will not receive a tooltip. You can pass in any CSS selector to initialize it. See document.querySelectorAll() for reference.

Here's how to create a tooltip for an element with an id of hello:

new Tippy('#hello')

Minimal Working Example, with all files in the same directory:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="tippy.css">
  </head>
  <body>
    <button id="myId" title="Tooltip text">Button text</button>
    <script src="tippy.js"></script>
    <script>
    new Tippy('#myId')
    </script>
  </body>
</html>

settingsCustomizing tooltips

Tippy's constructor takes an object as a second parameter for you to customize all tooltips being instantiated. Here's an example:

new Tippy('.tippy', { position: 'right', animation: 'fade' })

Result:

Data attributes

You can also specify settings on the element itself by adding data-* attributes. This overrides any global settings specified in the Tippy instance.

<button class="btn tippy" title="I'm a tooltip!" data-animatefill="false" data-animation="scale" data-position="bottom">Overridden</button>

Result:

This is helpful if you want to globally define settings, but make a few tooltips different without having to make a new Tippy instance.


settings_applicationsAll settings

Note: settings with camelCase are lowercase in HTML. For example, animateFill is data-animatefill in HTML.

Settingsettings Defaultremove Optionssettings_input_component Rolebuild
position 'top' 'top' 'bottom' 'left' 'right' Specifies which direction to position the tooltip on the element.
trigger 'mouseenter focus' 'mouseenter' 'focus' 'click' 'manual' Specifies which type of events will trigger a tooltip to show. mouseenter is for mouse/desktop devices and focus is for keyboard or touch/mobile devices. Use manual if you want to show/hide the tooltip manually/programmatically (see below).
interactive false true false Makes a tooltip interactive, i.e. will not close when the user hovers over or clicks on the tooltip. This lets you create a popover when used in conjunction with a click trigger.
delay 0 Any integer >= 0 (milliseconds) Specifies how long it takes after a trigger event is fired for a tooltip to show.
animation 'shift' 'shift' 'perspective' 'fade' 'scale' 'none' Specifies the type of transition animation a tooltip has.
arrow false true false Adds an arrow pointing to the tooltipped element. Setting this to true disables animateFill.
animateFill true true false Adds a material design-esque filling animation. This is disabled if you have arrow set to true.
duration 400 Any integer >= 0 (milliseconds) Specifies how long the transition animation takes to complete. Setting this to 0 will make it appear instantly. Tip! Large tooltips with animateFill look nicer with longer durations.
html false false or a template id Allows you to add HTML to a tooltip. See Creating HTML templates.
theme 'dark' 'dark' 'light' The CSS styling theme. You can add your own easily. See Creating themes.
offset 0 Any number (pixels) Offsets the tooltip on its opposite axis. For position top and bottom, it acts as offsetX. For position left and right, it acts as offsetY.
hideOnClick true true false Specifies whether to hide a tooltip upon clicking its element after hovering over.
multiple false true false Specifies whether to allow multiple tooltips open on the page (click trigger only).
followCursor false true false Specifies whether to follow the user's mouse cursor (mouse devices only).
popperOptions {} Object Allows deeper control over tooltip positioning and behaviour. See right below.

Finer control over tooltips

You can define a popperOptions setting with Popper.js settings. View the Popper.js documentation to see the settings you can specify.

Here's an example of how to integrate Popper.js settings into Tippy, so that a tooltip will flip to the bottom from the right if there's not enough room in the viewport.

new Tippy('.my-selector', {
    position: 'right',
    popperOptions: {
        modifiers: {
            flip: {
                behavior: ['right', 'bottom']
            }
        }
    }
})

Callbacks

If you want things to happen at certain times during a tooltip's show/hide events, you can add callback functions in the settings object. There are 4 to use:

new Tippy('.tippy', {
  beforeShown: function() {
    // When the tooltip has been triggered and has started to transition in
  },
  shown: function() {
    // When the tooltip has fully transitioned in and is showing
  },
  beforeHidden: function() {
    // When the tooltip has begun to transition out
  },
  hidden: function() {
    // When the tooltip has fully transitioned out and is hidden
  }
})

brushCreating themes

Tippy allows you to create your own theme for your tooltips easily. If you wanted to make a theme called honeybee, then your CSS would look like:

.tippy-tooltip.honeybee-theme {
  /* Your styling here. Example: */
  background-color: yellow;
  border: 2px solid orange;
}

Themes need the -theme suffix.

To style the arrow, target the element with an x-arrow attribute:

.tippy-tooltip.honeybee-theme [x-arrow] {
  /* Your arrow styling here. Uses transform: rotate() so no need for CSS triangle shenanigans. */
  background-color: yellow;
  border: 2px solid;
  border-color: transparent transparent orange orange; /* same for any position */
}

In case you want to target the content directly:

.tippy-tooltip.honeybee-theme .tippy-tooltip-content {
  /* Your styling here. Example: */
  color: black;
}

To style the animateFill circle, target the element with an x-circle attribute:

.tippy-tooltip.honeybee-theme [x-circle] {
  /* Your styling here. Example: */
  background-color: yellow;
}

Then, give your instance a theme setting with your theme's name:

new Tippy('.tippy', {
  theme: 'honeybee'
})

...or specify a data-theme attribute on your tooltipped element.

<button class="btn tippy" title="I'm a tooltip" data-theme="honeybee">Honeybee theme</button>

Example custom theme:


codeCreating HTML templates

It's worth noting that basic HTML can be injected straight into the element's title attribute. Example: title="<strong>text</strong>", so there's no need to create a template if you want something simple like that (though for backwards browser compatibility/fallback it won't look pretty). For more complex scenarios, use a template.

Regarding fallback. HTML template tooltips can't be shown to older browsers (IE <= 9), so you'll need to consider that when using them on your site.

Create an HTML template on the document. Set its style to display: none; so it won't be seen. You don't need to specify a title attribute with a HTML templated tooltip; it will be ignored. You may want to add a title attribute however to notify incompatible users of something.

<div id="my-template-id" style="display: none;">
  <p>Fun <strong>non-interactive HTML</strong> here</p>
  <img alt="cat" height="150" src="img/cat.jpg">
</div>

In your instance, specify its template id in the html setting.

new Tippy('#tooltip-with-my-template', {
  html: '#my-template-id',
  arrow: true,
  animation: 'fade'
})

Result:

Styling tooltips with HTML content

Use this selector to target your tooltip template. Replace "my-template-id" with your own template's id.

.tippy-tooltip[data-template-id="my-template-id"] {
  /* Your styling here. Example: */
  padding: 2rem;
}

Interactive elements also receive a class of active upon triggering so that you can still style hover effects when the user has moved the cursor away from the tooltipped element and onto the tooltip itself.

.my-tooltipped-element:hover, .my-tooltipped-element.active {
  /* Your hover styling here. */
}
You should disable animateFill when using HTML content. If the tooltip is tall, the circle element inside that creates the effect won't fill the entire tooltip. Non-textual content also breaks the effect's illusion.

settings_remoteControlling tooltips manually

Save the Tippy instance:

const instance = new Tippy('.tippy')

Find the element's popper reference by calling the method getPopperElement and passing in the element directly:

const popper = instance.getPopperElement(document.querySelector('#myElement'))
It must be a single tooltipped element.

Now you can show, hide, or destroy it.

instance.show(popper)

instance.hide(popper)

instance.destroy(popper)

The show method takes a transition duration as its second (optional) parameter.

destroying a popper removes listeners from its element and removes it from the global references array.


flash_onPerformance

As of v0.2.x, you can have hundreds of tooltipped elements without affecting page performance. Tooltips are only appended to the DOM when shown, and removed when hidden. Popper.js only listens to scroll and resize events when a popper (tooltip) is showing, and also updates the position on show.


schedulePlanned features

  • leaveDelay setting
  • More, cooler animations like inertia
  • Tooltips within HTML tooltips support
  • Setting for tooltip to follow mouse cursor
  • ...and some more as I think of them

License

MIT. Also check Popper.js' license.