Popper.js was updated to v2. The instance.popperInstance
and popperOptions
APIs have changed. You can
view its documentation here.
iife
was replaced with umd
(Rollup chunking has been removed).
To protect against XSS by default, allowHTML
is now false
by default. If
you're passing strings of HTML to content
, you must set allowHTML: true
.
View details
.tippy-tooltip
has become .tippy-box
, and theming is done via an attribute
now, to match the other props.
The following:
.tippy-tooltip.tomato-theme {
background-color: tomato;
}
Has become:
.tippy-box[data-theme~='tomato'] {
background-color: tomato;
}
The
~=
attribute operator allows you to specify mutliple theme names like before with class names.
For .tippy-arrow
, you'll need to specify its color on the ::before
pseudo-element.
The following:
.tippy-tooltip.tomato-theme[data-placement^='top'] > .tippy-arrow {
border-top-color: tomato;
}
Has become:
.tippy-box[data-theme~='tomato'][data-placement^='top'] > .tippy-arrow::before {
border-top-color: tomato;
}
In addition, if you were altering the pixel values, it may need to be adjusted.
In addition, Popper 2 changed some attribute names.
This:
.tippy-tooltip[data-out-of-boundaries] {
visibility: hidden;
}
Has become:
.tippy-box[data-reference-hidden] {
visibility: hidden;
}
View details
.tippy-popper
is no longer a selector, and is considered an implementation
detail for the most part now. [data-tippy-root]
attribute selector replaces it
if necessary.
View details
This no longer exists due to the user's ability to specify any structured DOM
with render()
(Headless Tippy).
To access the .tippy-box
element with the default render function
(.tippy-tooltip
in v5):
const box = instance.popper.firstElementChild;
View details
These no longer take a duration argument. Instead, use
.setProps({duration: ...})
before calling them if necessary.
To replicate .hide(0)
:
instance.unmount();
View details
Often, this was to solve a problem in Popper 1, where you set
boundary: "window"
. This is no longer necessary. If you'd like to change it
anyway, you can set it in popperOptions
:
tippy(targets, {
popperOptions: {
modifiers: [
{
name: 'preventOverflow',
options: {
// equivalent to boundary: 'window' in v1, usually NOT necessary in v2
rootBoundary: 'document',
},
},
],
},
});
View details
These have been merged into a single offset
prop, to match Popper 2's new API.
The following:
tippy(targets, {
offset: 5,
distance: 10,
});
Has become:
tippy(targets, {
offset: [5, 10],
});
This tuple also directly replaces offset: "5, 10"
.
View details
All of these have been removed. To configure these, specify them in
popperOptions
:
tippy(targets, {
placement: 'bottom',
popperOptions: {
modifiers: [
{
name: 'flip',
// flip: false
enabled: false,
options: {
// flipBehavior: ['bottom', 'right', 'top']
fallbackPlacements: ['right', 'top'],
},
},
],
},
});
flipOnUpdate
has no replacement yet. It's always true
.
View details
This has become an object to allow for better configurability. By default Tippy
will infer what to use (auto
), but this can be overridden.
Types:
interface Props {
// ...
aria: {
content?: 'auto' | 'describedby' | 'labelledby' | null;
expanded?: 'auto' | boolean;
};
}
tippy(targets, {
aria: {
// `null` when interactive is enabled
content: 'auto', // `aria-*` attribute
// `true` when interactive is enabled
expanded: 'auto', // `aria-expanded` attribute
},
});
View details
Due to static typing issues, it's been removed. Calling tippy()
again on the
same element will now always create a new tippy for it. Avoid calling tippy()
multiple times on the same reference if you don't want multiple tippies created
for it.
View details
It's now moveTransition
, which is a whole transition string. This allows you
to specify the easing function.
tippy(targets, {
moveTransition: 'transform 0.2s ease-out',
});
View details
It's been removed. The popperInstance
is now created and destroyed on
mount/unmount. If you were using this for ReferenceObjects, see below.
The following:
tippy(targets, {
lazy: false,
onCreate(instance) {
instance.popperInstance.reference = {
clientWidth: 0,
clientHeight: 0,
getBoundingClientRect() {
return {
// ...
};
},
};
},
});
Has become a single prop:
tippy(targets, {
getReferenceClientRect: () => ({
// ...
}),
});
This implements Popper 2's Virtual Elements API.
IE11 is not supported by default anymore, but can be polyfilled. View the Browser Support page on the documentation for details.
Make sure you have DEV warnings enabled by setting NODE_ENV=development
and
ensuring your bundler replaces process.env.NODE_ENV
with the string
"development"
.
- webpack: via
mode
option - Rollup: via
rollup-plugin-replace
- Parcel: automatic
- Browserify/Gulp/Grunt/others: View details
<script src="https://unpkg.com/popper.js@1"></script>
<!-- Specify development file -->
<script src="https://unpkg.com/tippy.js@5/dist/tippy-bundle.iife.js"></script>
<!--
When you're finished, you can remove everything after @5
(or when deploying for production)
<script src="https://unpkg.com/tippy.js@5"></script>
-->
Previously, the default import injected the CSS stylesheet into <head>
:
import tippy from 'tippy.js';
In v5, this import is now side-effect free to work better with dependencies when
users have CSP enabled or using frameworks that control the <head>
.
You should import the CSS separately:
import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
You can however opt-in to use the injected CSS version, just like v4:
// Just like v4
import tippy from 'tippy.js/dist/tippy-bundle.esm';
// Or CommonJS:
const tippy = require('tippy.js/dist/tippy-bundle.cjs');
This technique of auto initialization was removed to keep the import side-effect
free. Initializing via the tippy()
constructor is required.
View details
Node:
import tippy, {animateFill} from 'tippy.js';
import 'tippy.js/dist/tippy.css';
// These stylesheets are required for it to work
import 'tippy.js/dist/backdrop.css';
import 'tippy.js/animations/shift-away.css';
tippy(targets, {
animateFill: true,
plugins: [animateFill],
});
Browser:
<link rel="stylesheet" href="https://unpkg.com/tippy.js@5/dist/backdrop.css" />
<link
rel="stylesheet"
href="https://unpkg.com/tippy.js@5/animations/shift-away.css"
/>
<script src="https://unpkg.com/popper.js@1"></script>
<script src="https://unpkg.com/tippy.js@5"></script>
<script>
tippy(targets, {
content: 'tooltip',
animateFill: true,
});
</script>
View details
- Make sure your
visible
state has no translation (of 0px, instead of 10px like before). shift-away
,shift-toward
,scale
andperspective
need to be imported separately now.
Node:
import 'tippy.js/animations/scale.css';
Browser:
<link
rel="stylesheet"
href="https://unpkg.com/tippy.js@5/animations/scale.css"
/>
View details
When using interactive: true
, the tippy may be invisible or appear cut off if
your reference element is in a container with:
position
(e.g. fixed, absolute, sticky)overflow: hidden
To fix add the following prop (recommended):
tippy(reference, {
// ...
popperOptions: {
positionFixed: true,
},
});
Or, if the above causes issues:
tippy(reference, {
// ...
appendTo: document.body,
});
View details
Import the svg-arrow
CSS, and the roundArrow
string, and use the arrow
prop instead.
Node:
import {roundArrow} from 'tippy.js';
import 'tippy.js/dist/svg-arrow.css';
tippy(targets, {
arrow: roundArrow,
});
Browser:
<link rel="stylesheet" href="https://unpkg.com/tippy.js@5/dist/svg-arrow.css" />
<script>
tippy(targets, {
arrow: tippy.roundArrow,
});
</script>
View details
Node:
import tippy, {followCursor} from 'tippy.js';
tippy('button', {
followCursor: true,
plugins: [followCursor],
});
Browser:
(Works as before.)
View details
Node:
import tippy, {sticky} from 'tippy.js';
tippy('button', {
sticky: true,
plugins: [sticky],
});
Browser:
(Works as before.)
View details
Use delegate()
.
Node:
import tippy, {delegate} from 'tippy.js';
delegate('#parent', {target: 'button'});
Browser:
<script src="https://unpkg.com/popper.js@1"></script>
<script src="https://unpkg.com/tippy.js@5"></script>
<script>
tippy.delegate('#parent', {target: 'button'});
</script>
View details
It's now named showOnCreate
, to match the onCreate
lifecycle hook
View details
It's been removed, as it's more flexible to just use a theme and specify the
font-size
and padding
properties.
View details
Use touch: "hold"
instead.
View details
Ensure non-focusable elements have tabindex="0"
added to them. Otherwise, use
natively focusable elements everywhere possible.
View details
Use the onTrigger
and onUntrigger
lifecycles and temporarily disable the
instance.
tippy(targets, {
onTrigger(instance) {
instance.disable();
// Make your async call...
// Once finished:
instance.enable();
instance.show();
},
onUntrigger(instance) {
// Re-enable the instance here depending on the async cancellation logic
instance.enable();
},
});
View details
- instance.set({});
+ instance.setProps({});
View details
- tippy.defaults;
+ tippy.defaultProps;
- tippy.setDefaults({});
+ tippy.setDefaultProps({});
View details
In ESM/CJS contexts, it's no longer attached to tippy
Node:
import {hideAll} from 'tippy.js';
hideAll();
Browser:
(Works as before.)
View details
Use createSingleton()
.
Node:
import tippy, {createSingleton} from 'tippy.js';
createSingleton(tippy('button'), {delay: 1000});
Browser:
<script src="https://unpkg.com/popper.js@1"></script>
<script src="https://unpkg.com/tippy.js@5"></script>
<script>
tippy.createSingleton(tippy('button'), {delay: 1000});
</script>
View details
google
is nowmaterial
View details
[x-placement]
attribute is now[data-placement]
[x-out-of-boundaries]
is now[data-out-of-boundaries]
.tippy-roundarrow
is now.tippy-svg-arrow
.tippy-tooltip
no longer haspadding
on it, rather the.tippy-content
selector does..tippy-tooltip
no longer hastext-align: center
View details
Set instance.popperInstance.reference = ReferenceObject
in the onTrigger
lifecycle, or onCreate
with lazy: false
.
View details
Props
is notPartial
anymore, it'sRequired
Options
removed (usePartial<Props>
)BasicPlacement
renamed toBasePlacement