Features
Default
The default tooltip looks like this when Tippy is given no options. It has a nifty backdrop filling animation!
Placement compare_arrows
Tooltips can be placed in four different ways in relation to their reference element. Additionally, the tooltip can be shifted.
Arrows play_arrow
Arrows point toward the reference element. There are two different types of arrows: Sharp and Round. You can transform the proportion and scale of the arrows any way you like.
Triggers touch_app
Triggers define the types of events that cause a tooltip to show. A fourth trigger, Manual, is used when you want to programmatically show or hide a tooltip.
Interactivity pan_tool
Tooltips can be interactive, meaning you can hover over or click on them and they won't hide.
Animations blur_on
Tooltips can have different types of transition animations.
Transitions & Delays timer
Tooltips can have different transition durations or delays.
Themes brush
You can create all kinds of custom funky themes for your tooltips with ease.
Callbacks call
Callbacks allow you to react to a tooltip's show and hide events. Open your browser console to see when the logs occur.
HTML code
Tooltips can even contain HTML!
Misc tag_faces
Tippy has many more features! These are just some of them.
tag_facesGetting started
file_download Download the latest release (.zip)
Alternatively, you can install through npm:
npm install --save tippy.js@2.0.9
Or use the unpkg.com CDN:
https://unpkg.com/tippy.js@2.0.9/dist/
Simply include the tippy.all.min.js
file in your document before your own scripts:
<script src="https://unpkg.com/tippy.js@2.0.9/dist/tippy.all.min.js"></script>
This is the bundled version which includes Popper.js and automatically injects Tippy's CSS stylesheet into the document head.
Use tippy.standalone.js
if you want to use a different version of Popper.js.
buildCreating a tooltip
First, give your element(s) a title
attribute containing what you want the tooltip to say.
<button class="btn" title="I'm a tooltip!">Text</button>
Then, to give them a Tippy tooltip, call the tippy()
function by passing in a CSS selector.
tippy('.btn')
Result:
To give all elements with a title
attribute a tooltip, you can use:
tippy('[title]')
For details on the type of CSS selector string you can use, see document.querySelectorAll() for reference.
Additional selector options
You aren't limited to just a CSS selector string as input. You can also directly use a DOM element (or an array of elements):
tippy(document.querySelector('#myElement'))
Or a NodeList:
tippy(document.querySelectorAll('.myElements'))
Advanced
For more specialized cases, you can also pass in a custom virtual object instead of a DOM node to act as the positioning reference.
const refObject = {
attributes: {
title: 'Tooltip text'
},
getBoundingClientRect() {
return {
top: 5 + window.pageYOffset,
left: 5 + window.pageXOffset,
right: 5 + window.pageXOffset,
bottom: 220 + window.pageYOffset,
width: 1,
height: 1
}
},
get clientWidth() {
return 30
},
get clientHeight() {
return 30
},
}
tippy(refObject)
Elements without a title
attribute (or an empty title) and without an HTML template will not receive a tooltip.
settingsCustomizing tooltips
tippy()
takes an object as a second argument for you to customize the tooltips being instantiated. Here's an example:
tippy('.btn', {
placement: 'right',
animation: 'scale',
duration: 1000,
arrow: true
})
Result:
Data attributes
You can also specify options on the element itself by adding data-tippy-*
attributes. This overrides any global options specified in the instance.
<button
class="btn tippy"
title="I'm a tooltip!"
data-tippy-duration="[275, 250]"
data-tippy-arrow="false"
data-tippy-animation="shift-away"
data-tippy-placement="bottom"
>
Overridden
</button>
Result:
This is helpful if you want to globally define options, but make a few tooltips different without having to call tippy()
again with different options.
settings_applicationsAll options
Note: options with camelCase are lowercase in HTML. For example, animateFill
is data-tippy-animatefill
in HTML.
Optionsettings | Defaultremove | Inputssettings_input_component | Rolebuild |
---|---|---|---|
placement |
'top' |
'top' 'bottom' 'left' 'right'
|
Specifies which direction to place the tooltip in relation to the reference element.
Add the suffix -start
or -end to shift the placement. 'top-end' is an example.
|
trigger |
'mouseenter focus' |
'mouseenter' 'focus' 'click' 'manual' {custom} |
Specifies which type of events will trigger a tooltip to show. Separate each by a space.
mouseenter is for hovering and touch on mobile, and focus is for keyboard navigation.
Use manual if you want to show/hide the tooltip manually
(see the Methods section below).
{custom} refers to the fact that you can have any event listener, but it won't have the opposite "hide" event.
|
dynamicTitle |
false |
Boolean |
Whenever the title attribute on the reference element changes, the tooltip will automatically be updated. |
interactive |
false |
Boolean |
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 (similar to Bootstrap) when used in conjunction with a click trigger. |
interactiveBorder |
2 |
Number (pixels) |
Specifies the size of the invisible border around an interactive tooltip that will prevent it from closing. Only applies to mouseenter triggered tooltips. |
animation |
'shift-away' |
'shift-away' 'shift-toward' 'perspective' 'fade' 'scale' |
Specifies the type of transition animation a tooltip has. |
animateFill |
true |
Boolean |
Adds a material design-esque filling animation. This is disabled if you have arrow set to true . |
arrow |
false |
Boolean |
Adds an arrow pointing to the reference element. Setting this to true disables animateFill . |
arrowType |
'sharp' |
'sharp' 'round' |
Specifies the type of arrow to use. Sharp is a CSS triangle, whereas Round is a custom SVG shape. |
arrowTransform |
'' |
Transform CSS | Allows you to transform the arrow, such as the proportion using scale.
Because of flipping, the syntax becomes dynamic. You must use the syntax that gives the desired results for the top placement, even if you
use a different placement. Only translate and scale are supported
for dynamic syntax.
'scaleX(1.5)' = wider arrow'scaleX(0.5)' = narrower arrow'scale(0.5)' = smaller arrow'scale(1.5)' = larger arrow'translateY(-5px)' = arrow closer to tooltip'translateY(5px)' = arrow farther from tooltip
|
delay |
0 |
Number | Array (milliseconds) |
Specifies how long it takes after a show or hide event is fired for a tooltip to begin showing or hiding.
Use an array to specify a different show and hide delay, such as [300, 100] .
|
flip |
true |
Boolean
|
Specifies whether the tooltip should flip (the reversing of placement based on the amount of room in the viewport to display a tooltip). |
flipBehavior |
'flip' |
'flip'
'clockwise'
'counterclockwise' |
Array of placement strings
|
Specifies the flipping behavior of a tooltip. Based on the amount of room in the viewport,
the tooltip will choose which placement to use. For example, 'clockwise' with a
placement of 'right' will flip to the bottom when there is not enough room.
|
maxWidth |
'' |
String with unit |
Specifies the maximum width of a tooltip. Ensure you add units, such as px, rem, etc. |
duration |
[350, 300] |
Number | Array (milliseconds) |
Specifies how long the transition animation takes to complete.
A single number will use the same duration for the show and hide events.
Use an array to specify a different show and hide duration, such as [300, 100] .
|
html |
false |
false | template id | Element |
Allows you to add HTML to a tooltip. See Creating HTML templates. |
size |
'regular' |
'small' 'regular' 'large' |
Specifies how large the tooltip is. |
distance |
10 |
Number (pixels) |
Specifies how far away the tooltip is from its reference element. This contrasts
the offset option in that it only applies to a single axis and allows
tooltips to still be interactive when their trigger is mouseenter . |
theme |
'dark' |
'dark' |
You can create your own easily. See Creating themes. |
offset |
0 |
Number | String (pixels) |
Offsets a tooltip on a certain axis. Use a string such as '25, 10' to offset it on both the x and y axes. |
hideOnClick |
true |
true false 'persistent' |
Specifies whether to hide a tooltip upon clicking its reference element after hovering over and when clicking elsewhere on the document. For click-triggered tooltips when using false , toggle functionality remains unless you use 'persistent' . |
multiple |
false |
Boolean |
Specifies whether to allow multiple tooltips open on the page (click trigger only). |
followCursor |
false |
Boolean |
Specifies whether to follow the user's mouse cursor (mouse devices only). |
inertia |
false |
Boolean |
Modifies the transition-timing-function with a cubic bezier to create a "slingshot" intertial effect. |
updateDuration |
300 |
Number (milliseconds) |
Specifies the transition duration between flips and when updating a tooltip's position on the document. |
sticky |
false |
Boolean |
Specifies whether the tooltip should stick to its reference element when it's showing (for example, if the element is animated/moves). |
appendTo |
document.body |
Element | Function |
Specifies which element the tooltip popper is appended to. Use a function which returns an Element for more advanced use cases. |
zIndex |
9999 |
Number |
Specifies the z-index of the tooltip popper. |
touchHold |
false |
Boolean |
Changes the trigger behavior on touch devices. It will change it from a tap to show and tap off to hide, to a tap and hold to show, and a release to hide. |
performance |
false |
Boolean |
Disables data-tippy-* attribute options to make initial instantiation time faster. |
onShow |
- | Function |
Callback function triggered when a tooltip begins to show. |
onShown |
- | Function |
Callback function triggered when a tooltip has fully transitioned in. |
onHide |
- | Function |
Callback function triggered when a tooltip begins to hide. |
onHidden |
- | Function |
Callback function triggered when a tooltip has fully transitioned out. |
createPopperInstanceOnInit |
false |
Boolean |
By default, the popper instance for a tooltip is not created until it is shown for the first time
in order to optimize performance.
In some cases this may cause issues, so you can specify it to be created when you init with tippy() .
Safari seems to stutter slightly when the tooltip is shown for the first time. Certain CSS effects may also cause the transition to stutter on the first show. For these certain cases, you may want to set this option to true .
|
popperOptions |
{} |
Object |
Allows more control over tooltip positioning and behavior. See right below. |
Modify the default options
You can change the default options by accessing them via tippy.defaults
, which will apply to every tippy instance.
Finer control over tooltips
You can define a popperOptions
option with Popper.js options.
View the Popper.js documentation
to see the options you can specify.
Tooltips inside a scrollable container
You may encounter issues with tooltip positioning when it's given to an element within a scrollable container.
Firstly, when the element is no longer visible, the tooltip will stay stuck within the viewport. Secondly, it transitions between position updates.
To solve this, simply specify a updateDuration
of 0
and add the following popperOptions
:
tippy('.mySelector', {
updateDuration: 0,
popperOptions: {
modifiers: {
preventOverflow: {
enabled: false
}
}
}
})
Callbacks
If you want things to happen at certain times during a tooltip's show/hide events, you can add callback functions in the options object. There are 5 to use:
tippy('.btn', {
onShow: function () {
// When the tooltip has been triggered and has started to transition in
},
onShown: function () {
// When the tooltip has fully transitioned in and is showing
},
onHide: function () {
// When the tooltip has begun to transition out
},
onHidden: function () {
// When the tooltip has fully transitioned out and is hidden
},
wait: function (show, event) {
// See below for an explanation
}
})
this
inside the callbacks refers to the popper being shown or hidden.
wait
is a special callback that allows you to control the show
method
for easier integration into UI libraries like React when using HTML tooltips with components.
To show the tooltip once you have done the necessary steps inside the function, simply invoke show()
.
AJAX tooltips
Callbacks allow you to do powerful things with tooltips. Here's an example of dynamic content which on show, fetches a new random image from the Unsplash API. Note: this requires a browser which supports the newer fetch API.
Reactivity
Tooltips react to content changes. For example, if a paragraph element inside the tooltip is removed or changed, the tooltip will automatically update its position.
Note: This isn't supported in IE10 natively (unless polyfilled) because it uses MutationObserver
.
Disabling tooltips on touch devices
It can be tricky to determine touch devices accurately, especially considering the existence of hybrid devices (a mix of mouse and touch input). Simply detecting the user agent is not enough.
A user can switch between either input type at any time which is why dynamic input detection is enabled. You can hook into Tippy's detection of user input changes by defining the following callback function:
tippy.browser.onUserInputChange = function (type) {
console.log('The user is now using', type, 'as an input method')
}
Whenever the user changes their input method, you can react to it inside the callback function. To disable tooltips for touch input but keep them enabled for mouse input, you can do the following:
const tip = tippy('[title]')
tippy.browser.onUserInputChange = function (type) {
const method = type === 'touch' ? 'disable' : 'enable'
for (const tooltip of tip.tooltips) {
tooltip[method]()
}
}
Hiding tooltips on scroll
Due to the way browsers fire mouseleave
events, it may be desirable to
hide tooltips and immediately disable their event listeners whenever scrolling occurs.
This might also help reduce the intrusiveness of a tooltip on small screen touch devices,
as it will begin hiding out of the way whenever they scroll, rather than whenever they
tap somewhere else.
window.addEventListener('scroll', function () {
const poppers = document.querySelectorAll('.tippy-popper')
for (const popper of poppers) {
const tooltip = popper._reference._tippy
if (tooltip.state.visible) {
tooltip.popperInstance.disableEventListeners()
tooltip.hide()
}
}
})
settings_remoteMethods
Suppose you have the following element which has been given a Tippy tooltip:
<button id="myButton" title="Tooltip">My element</button>
const btn = document.querySelector('#myButton')
tippy(btn)
Every element with a Tippy tooltip is given an attribute of data-tippy
:
<button id="myButton" title="Tooltip" data-tippy>My element</button>
The Tippy instance is stored on the reference element via the _tippy
property:
btn._tippy
Tippy instances have 5 methods: enable()
, disable()
,
show()
, hide()
, and
destroy()
.
This allows you to control the tooltip without the use of UI events.
Show the tooltip
btn._tippy.show()
Hide the tooltip
btn._tippy.hide()
Pass a number in as an argument to specify a custom transition duration in milliseconds:
btn._tippy.show(500)
btn._tippy.hide(500)
Destroy the tooltip
btn._tippy.destroy()
Destroying the tooltip will delete the _tippy
property from the reference element.
To destroy all the tooltips that were created, use the destroyAll()
method on the object
returned from tippy()
:
const tip = tippy('.btn')
tip.destroyAll()
tip.tooltips
is an array that contains all the individual Tippy instances that were created.
Disable/enable the tooltip
In cases where you want to temporarily disable a tooltip from showing or hiding but NOT destroy it,
you can use the disable()
method.
btn._tippy.disable()
To re-enable it:
btn._tippy.enable()
Update the tooltip
In V1, for tooltips whose content needed to be changed, there was an update()
method. This has been replaced by a much easier way.
For standard tooltips, simply set the dynamicTitle
option to true
.
tippy(btn, {
dynamicTitle: true
})
Whenever the title attribute on the reference element changes, the tooltip's content will automatically be updated.
Retrieve the reference element from a popper
The reference element is attached to the popper element via the _reference
property.
popper._reference
An example of this being useful is when handling a click event inside the popper element, and needing to know which element it refers to (and therefore its Tippy instance).
popper._reference._tippy
Get all Tippy instances
Getting all (non-destroyed) Tippy instances on the document can be done in one single line:
Array.from(document.querySelectorAll('[data-tippy]'), el => el._tippy)
This returns an array holding every current Tippy instance which can be filtered or manipulated in any way.
codeCreating HTML templates
There are two options you have when creating a template. You can either clone it or use it directly.
Cloning
Use the template's id
selector string.
Option: html: '#myTemplate'
- Can be re-used multiple times
- Not removed from the page
- Will not save event listeners attached to it
- Not directly modifiable
Direct
Use Element
directly.
Option: html: document.querySelector('#myTemplate')
- Can only be used once
- Removed from the page and appended directly to the tooltip
- Saves event listeners attached to it
- Directly modifiable
Example HTML template
style="display: none;"
to hide the template.
<div id="myTemplate">
<p>Fun <strong>non-interactive HTML</strong> here</p>
<img alt="cat" height="150" src="img/cat.jpg">
</div>
tippy('#myElement', {
html: document.querySelector('#myTemplate'), // Direct element option
arrow: true,
animation: 'fade',
distance: 15,
arrowTransform: 'scale(2)'
})
Result:
Updating tooltips with HTML content
For HTML tooltips, save your template to a variable in order to modify it later.
const template = document.querySelector('#myTemplate')
tippy(btn, {
html: template
})
template.innerHTML = 'Updated!'
If you want to re-use the template multiple times, use cloneNode(true)
:
const template = document.querySelector('#myTemplate')
const clonedTemplate = template.cloneNode(true)
tippy(btn, {
html: clonedTemplate
})
clonedTemplate.innerHTML = 'Updated!'
// template.innerHTML remains unaffected
Dynamically pulling HTML content
You can use a function instead of an element reference as the html
setting.
The function will be executed with one argument: the element the tooltip is being added to.
This is useful for cases in which you have multiple elements, each one having its own unique tooltip.
tippy('.myElements', {
html: el => el.querySelector('.popup')
})
Styling tooltips with HTML content
Use this selector to target your tooltip template. Replace "#my-template-id" with
your own template's id
, including the leading hash. If you're using a DOM element
in the html
setting and no id
is found,
it defaults to tippy-html-template
.
.tippy-tooltip[data-template-id="#my-template-id"] {
/* Your styling here. Example: */
padding: 2rem;
}
Interactive elements also receive a class of tippy-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.tippy-active {
/* Your hover styling here. */
}
brushCreating themes
Creating a theme for your tooltips is easy. 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.
Style the arrow
To style the arrow, target the element with a tippy-arrow
or
tippy-roundarrow
class:
.tippy-popper[x-placement^=top] .tippy-tooltip.honeybee-theme .tippy-arrow {
/* Your arrow styling here. */
}
In this example, the arrow is being styled when the tooltip placement begins with top
.
You will need to target a specific popper placement (top, bottom, left, right) because the arrow will change
based on the placement.
Sharp arrows are CSS triangles which use the border trick, while round arrows are an SVG
shape which can have their color changed with fill
.
Style content directly
.tippy-tooltip.honeybee-theme .tippy-content {
/* Your styling here. Example: */
color: black;
}
Style the animateFill backdrop
.tippy-tooltip.honeybee-theme .tippy-backdrop {
/* Your styling here. Example: */
background-color: yellow;
}
Specify a theme
tippy('.btn', {
theme: 'honeybee'
})
...or specify a data-tippy-theme
attribute on the reference element.
<button class="btn tippy" title="I'm a tooltip" data-tippy-theme="honeybee">Honeybee theme</button>
Example custom theme:
Multiple themes
Add multiple themes by separating each by a space.
tippy('.btn', {
theme: 'menu light'
})
This will add the classes .menu-theme
and .light-theme
to the tooltip's class list.
important_devices Browser support
Tippy gracefully degrades on older browsers (and with JavaScript disabled) by using the
browser's default title
tooltip.
Supported browsers
Browsers which support requestAnimationFrame
.
See caniuse. If
your audience has low Opera Mini usage (common in western countries), then support should be
>96%.
Touch devices
Tippy supports touch devices. Standard behavior is to tap an element to show its tooltip, and then tap elsewhere to hide it. It's also possible to change the behavior so that you can tap-and-hold to show it, then release to hide it.
Dynamic input detection
For certain options to work reliably depending on the type of user input (such as mouse or touch),
dynamic input detection is enabled by default. To disable this behavior, set dynamicInputDetection
to false
:
tippy.browser.dynamicInputDetection = false
To see Tippy's browser
settings:
tippy.browser
Accessibility
Tooltips have ARIA labelling to ensure accessibility.
Browser quirks
Certain browsers are buggy and don't handle things perfectly. Tippy tries to work around them, but here's a known list of issues:
-
iOS browsers don't animate
clip-path
smoothly, so it is disabled. This only applies to theanimateFill
backdrop filling animation. IE10+ and Edge don't support it at all yet. The text will overflow when transitioning if the text is not the same color as the background. -
UC Browser disables
border-radius
with the backdrop filling animation.
flash_onPerformance
You can have thousands of tooltipped elements without affecting page performance after the initial instantiation. 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.
Note: these tooltips are created with performance
mode set to true
.
License
MIT. Also check Popper.js' license.