## Features

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

##### NOTE: These docs refer to v1. New features from minor version increases are highlighted. Make sure you're up to date!

## 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 works on touch devices almost the same as on desktop/mouse devices. However on iOS devices, in order for tooltips to close when tapping anywhere on the body and to trigger hover events on non-clickable elements, a `.tippy-touch { cursor: pointer !important; }` class is added to the body.

#### Dynamic input detection

For certain settings to work reliably depending on the type of user input (such as mouse or touch), dynamic input detection is enabled by default. To disable or enable, use:

    tippy.enableDynamicInputDetection()
    tippy.disableDynamicInputDetection()

You may also access the `Browser` object settings set internally via:

    tippy.Browser

#### Accessibility

Tooltips have ARIA labelling to ensure accessibility.

## tag_faces Getting started

file_download Download the latest release (.zip)

Alternatively, you can install through npm:

    npm install --save tippy.js@1.4.2

or use the unpkg.com CDN:

    https://unpkg.com/tippy.js@1.4.2/dist/

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

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

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

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

If you installed the npm package, the JS and CSS files are available in the dist folder:

    tippy.js
    tippy.min.js
    tippy.standalone.js
    tippy.css

`tippy.js` comes bundled with `popper.js` (unminified), and `tippy.standalone.js` (minified) is Tippy by itself if you want use a different version of Popper.js.

## build Creating a tooltip

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

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

Then, to give it a Tippy tooltip, call the `tippy()` function by passing in a CSS selector.

    tippy('.btn')

Result:

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: v1.3

    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. v1.4

    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.

## settings Customizing tooltips

`tippy()` takes an object as a second argument for you to customize the tooltips being instantiated. Here's an example:

    tippy('.tippy', {
      position: 'right',
      animation: 'scale',
      duration: 1000,
      arrow: true
    })

Result:

#### Data attributes

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

    <button
      class="btn tippy"
      title="I'm a tooltip!"
      data-duration="[400, 0]"
      data-arrow="false"
      data-animation="shift"
      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 call `tippy()` again with different settings.

## settings_applications All 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. Add the suffix `-start` or `-end` to shift the position. `'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.
`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.
`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]`.
`animation` | `'shift'` | `'shift'` `'perspective'` `'fade'` `'scale'` | Specifies the type of transition animation a tooltip has.
`arrow` | `false` | `Boolean` | Adds an arrow pointing to the tooltipped element. Setting this to `true` disables `animateFill`.
`arrowSize` | `'regular'` | `'small'` `'regular'` `'big'` | Specifies how big the tooltip's arrow is. The sizes are 5px, 7px and 10px respectively.
`animateFill` | `true` | `Boolean` | Adds a material design-esque filling animation. This is disabled if you have `arrow` set to `true`.
`duration` | `350` | `Number` | `Array` (milliseconds) | Specifies how long the transition animation takes to complete when showing a tooltip. 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'` `'big'` | Specifies how big the tooltip is.
`distance` | `10` | `Number` (pixels) | Specifies how far away the tooltip is from its element.
`theme` | `'dark'` | `'dark'` `'light'` `'transparent'` | The CSS styling theme. You can add 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 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.
`flipDuration` | `300` | `Number` (milliseconds) | Specifies the transition duration between flips and when updating a tooltip's position on window resize.
`sticky` | `false` | `Boolean` | Specifies whether the tooltip should stick to its element reference when it's showing (for example, if the element is animated/moves).
`stickyDuration` | `200` | `Number` (milliseconds) | Specifies the 'smoothing' transition when the popper's position updates as its element moves.
`appendTo` | `document.body` | `Element` | Specifies which element the tooltip popper is appended to.
`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-*` attribute settings to make initial instantiation time faster.
`dynamicTitle` | `false` | `Boolean` | Whenever the `title` attribute on the reference element changes, the tooltip will automatically be updated.
`popperOptions` | `{}` | `Object` | Allows more control over tooltip positioning and behavior. 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.

    tippy('.mySelector', {
      position: 'right',
      popperOptions: {
        modifiers: {
          flip: {
            behavior: ['right', 'bottom']
          }
        }
      }
    })

#### Flipping

By default, tooltips will flip on their opposite axis if there is not enough room in the viewport. If you want to force no flip, then use:

    tippy('.mySelector', {
      popperOptions: {
        modifiers: {
          flip: {
            enabled: false
          }
        }
      }
    })

#### 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 `flipDuration` of `0` and add the following `popperOptions`:

    tippy('.mySelector', {
      flipDuration: 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 settings object. There are 5 to use:

Note: Callback functions prior to v1.1 should not have the `on` prefix; simply use `show`, `hide`, etc. However, starting from v1.1 they are deprecated in favor of the more semantic `on*` names which better indicate a callback function.

    tippy('.tippy', {
      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. The function itself takes a callback as a parameter, which is just the `show` method for the tooltip.

Example usage (ES6 syntax):

    tippy('.tippy', {
      wait(show, event) {
        // Change your app model to be rendered by the UI library/framework

        // Queue show to run once rendering is complete
        setTimeout(() => {
          // update(popper) content
          // event.type to see what trigger fired the event

          show()
        }, 0)
      }
    })

See here for reference.

#### Modify the default settings

You can change the default settings by accessing them via `tippy.Defaults`.

## settings_remote Methods

`tippy()` returns a new Tippy object with the following methods available:

- `getPopperElement` - returns the tooltip popper element
- `getReferenceElement` - returns the element that has the tooltip
- `getReferenceData` - returns the object containing information about the reference
- `show` - shows a tooltip
- `hide` - hides a tooltip
- `update` - updates a tooltip with new content
- `destroy` - destroys an individual tooltip
- `destroyAll` - destroys all tooltips created by the instance

#### Terminology

The `popper` is the parent element while the `tooltip` is the child of the popper.

The element you give the tooltip to is called the `reference` element.

#### Showing and hiding tooltips programmatically

    <button id="myButton" title="Tooltip">My element</button>

First, save the instance:

    const tip = tippy('#myButton')

Next, find the reference element's popper reference by calling the method `getPopperElement` and passing the element in directly:

    const el = document.querySelector('#myButton')
    const popper = tip.getPopperElement(el)

Then, call the `show()` or `hide()` method by passing in the popper element:

    tip.show(popper)
    tip.hide(popper)

Pass a number in the second argument to specify a transition duration:

    tip.show(popper, 500)

#### Finding the reference element from the popper element

Pass the popper element to find its reference element into this method:

    const el = tip.getReferenceElement(popper)

#### Updating a tooltip with new content

The `update()` method will check for a new `title` attribute on the element that has the tooltip.

    el.setAttribute('title', 'New content!')
    tip.update(popper)

If it's a HTML template instead, it will inject the new HTML of the template.

#### Destroying tooltips

The `destroy()` method will destroy an individual tooltip.

    tip.destroy(popper)

The `destroyAll()` method will destroy every tooltip created by the instance.

    tip.destroyAll()

#### Reference data

Retrieve the data object for a particular tooltip reference by passing in either the reference element or the popper element.

    const data = tip.getReferenceData(el || popper)

This object contains information about a reference element and its popper element.

In order to optimize performance, the `popperInstance` property is not created until the tooltip is shown for the first time, so the data object will not contain it until you've shown a tooltip at least once.

#### AJAX 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.

Loading a new image...

Codepen demo

#### Reactivity v1.1

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`.

## code Creating 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

When cloning, use `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>

Fun non-interactive HTML here

    tippy('#myElement', {
      html: document.querySelector('#myTemplate'), // DIRECT ELEMENT option
      arrow: true,
      animation: 'fade'
    })

Result:

#### 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('.my-elements', {
      html: el => el.querySelector('.popup')
    })

#### Styling tooltips with HTML content

Use this selector to target your tooltip template. Replace "#myTemplate" 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="#myTemplate"] {
      /* 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. */
    }

## brush Creating 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. */
    }

Arrows are CSS triangles, read this comment to see how to style arrows properly.

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, specify a `theme` setting with your theme's name:

    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:

#### Multiple themes

Add multiple themes by separating each by a space.

    tippy('.tippy', {
      theme: 'menu light'
    })

This will add the classes `.menu-theme` and `.light-theme` to the tooltip's class list.

## flash_on Performance

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`.

Elements to append

#### License

MIT. Also check Popper.js' license.

This is an example of an interactive HTML tooltip created with a template.

## CAT!