Skip to content
Tippy Logo




Tippy elements use a simple CSS fade transition by default.

#Included animations

The tippy.js package comes with extra animations for you to use:

  • shift-away
  • shift-toward
  • scale
  • perspective

They need to be imported separately.

import 'tippy.js/animations/scale.css';

Pass the animation name (string) as the animation prop:

tippy('button', {
  animation: 'scale',

Each of these 3 animations also has 3 variants (normal, subtle, and extreme).

import 'tippy.js/animations/scale.css';
import 'tippy.js/animations/scale-subtle.css';
import 'tippy.js/animations/scale-extreme.css';
// `perspective` and `shift-toward` follow the same format as above

#Custom animations

If the extra packaged animations don't suit your use case, you can create your own.

You'll need to:

  • Use your own animation name in the [data-animation] attribute selector
  • Target the visibility state of the tippy: [data-state="hidden"] or [data-state="visible"]
  • Depending on the animation, target the placement of the tippy too: e.g. [data-placement^="top"]
.tippy-tooltip[data-animation='my-animation'][data-state='hidden'] {
  transform: rotate(90deg);
tippy('button', {
  animation: 'my-animation',


There's a prop named inertia that adds an elastic inertial effect to the tippy, which is a limited CSS-only way to mimic spring physics.

tippy('button', {
  inertia: true,

You can customize this prop in your CSS:

.tippy-tooltip[data-inertia][data-state='visible'] {
  transition-timing-function: cubic-bezier(...);

#Material filling effect

Import the animateFill plugin, plus dist/backdrop.css & animations/shift-away.css stylesheets.

import tippy, {animateFill} from 'tippy.js';
import 'tippy.js/dist/backdrop.css';
import 'tippy.js/animations/shift-away.css';

tippy(reference, {animateFill: true}, [animateFill]);

#CSS animations

Maybe plain transitions aren't enough for your use case. You can also use CSS animations (e.g. animate.css):

tippy('button', {
  // 'fade' is just an opacity transition, which is a good base for most
  // animations
  animation: 'fade',
  onMount(instance) {
    const {tooltip} = instance.popperChildren;
    requestAnimationFrame(() => {
  onHidden(instance) {
    const {tooltip} = instance.popperChildren;

You can also use @keyframes and add the animation property to your animation selector too.

#Dimensions transition

While a tippy is showing, the content inside of it may change. How do you smoothly transition its dimensions? By default, it instantly changes size when the content is updated. It turns out this is quite complex to do, but possible.

#Partially dynamic

View the CodePen demo.

#Fully dynamic

Code for fully dynamic transitions is still being developed and it is highly experimental at this stage. The documentation will be updated once it's ready.