Skip to content
Tippy Logo


View on GitHub
Currently v6.3.0


Tippies can have any custom styling via CSS.

#Included themes

The package comes with themes for you to use:

  • light
  • light-border
  • material
  • translucent

They need to be imported separately.

import 'tippy.js/themes/light.css';

Pass the theme name as the theme prop:

tippy('button', { theme: 'light', });

#Tippy elements

To learn how to create a theme, it's helpful to understand the basic structure of a tippy element:

<div data-tippy-root> <div class="tippy-box" data-placement="top"> <div class="tippy-content"> My content </div> </div> </div>

A tippy is essentially three nested divs.

  • [data-tippy-root] is the outermost node. It is what Popper uses to position the tippy. You don't need to apply any styles to this element.
  • tippy-box is the actual box node.
  • tippy-content is the content node.

Depending on the props supplied, there will exist other elements inside it:

<div data-tippy-root> <div class="tippy-box" data-placement="top"> <div class="tippy-backdrop"></div> <!-- animateFill: true --> <div class="tippy-arrow"></div> <!-- arrow: true --> <div class="tippy-content"> My content </div> </div> </div>

#Creating a theme

Themes are created by including a class on the tippy-box element as part of a selector in the form .tippy-box[data-theme~='theme']. Let's demonstrate this by creating our own theme called tomato:

.tippy-box[data-theme~='tomato'] { background-color: tomato; color: yellow; }

To apply the theme:

tippy(targets, { theme: 'tomato', });

What is ~=?

Since theme can have multiple names, it allows you to target a single theme inside the space-separated list. Visit MDN for more information.

#Styling the arrow

There are two types of arrows:

  • CSS arrows (using border-width)
  • SVG arrows (using an <svg> element)

#CSS arrow

To style the default CSS arrow, target each different base placement using the data-placement attribute and apply it to the .tippy-arrow element's ::before pseudo-element:

.tippy-box[data-theme~='tomato'][data-placement^='top'] > .tippy-arrow::before { border-top-color: tomato; } .tippy-box[data-theme~='tomato'][data-placement^='bottom'] > .tippy-arrow::before { border-bottom-color: tomato; } .tippy-box[data-theme~='tomato'][data-placement^='left'] > .tippy-arrow::before { border-left-color: tomato; } .tippy-box[data-theme~='tomato'][data-placement^='right'] > .tippy-arrow::before { border-right-color: tomato; }

#SVG arrow

First import the svg-arrow.css stylesheet for SVG arrow styling:

import 'tippy.js/dist/svg-arrow.css';

To color an SVG arrow, specify fill and target .tippy-svg-arrow:

.tippy-box[data-theme~='tomato'] > .tippy-svg-arrow { fill: tomato; }

The shape isn't dependent on the placement for styling, which is why it doesn't require the CSS arrow's more verbose styles.

There is a default round arrow SVG shape exported from the package for you to use.

#CDN (umd)

tippy(targets, { arrow: tippy.roundArrow, });

#Modules (esm)

import {roundArrow} from 'tippy.js'; tippy(targets, { arrow: roundArrow, });

#Changing the arrow size

#Option 1: transform: scale()

This is the easiest technique and works for most cases:

.tippy-box[data-theme~='tomato'] > .tippy-arrow::before { transform: scale(1.5); }

#Option 2: Pixel increase

If your tippy theme has a border (e.g. the included light-border theme), then the transform: scale() technique distorts the border width of the arrow. Instead, you will need to change the size of the arrow in pixels directly.

#Arrow border

There is a stylesheet to aid in adding borders to your tippies:

import 'tippy.js/dist/border.css';

This adds color inheritance for borders when using the default CSS arrow, and aids in creating SVG arrow borders.

#CSS arrow

/* The border of the arrow will now match the border of the box */ .tippy-box[data-theme~='tomato'] { background: tomato; border: 1px solid yellow; }

#SVG arrow

Duplicate the SVG arrow so that there are two of them, like so:

tippy(targets, { // concatenates the two SVG strings together arrow: roundArrow + roundArrow, });
/* The border */ .tippy-box[data-theme~='tomato'] > .tippy-svg-arrow > svg:first-child { fill: yellow; } /* The fill */ .tippy-box[data-theme~='tomato'] > .tippy-svg-arrow > svg:last-child { fill: tomato; }

#Browser DevTools

It's highly recommended you inspect a tippy element via your browser's DevTools. An easy way to do this is to give it hideOnClick: false and trigger: 'click' props so that it stays visible when focus is switched to the DevTools window.

The tippy element gets appended to the very end of the <body>, so you should scroll down the elements panel. If interactive: true, then the tippy is appended to the reference element's parentNode instead.

HTML ContentAnimations

© 2021 — MIT License

Icons made by Freepik from