Themes
Tippies can have any custom styling via CSS.
Base Style
import 'tippy.js/dist/tippy.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:
useTippy(target, {
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 div
s.
[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 calledtomato
:
.tippy-box[data-theme~='tomato'] {
background-color: tomato;
color: yellow;
}
To apply the theme:
useTippy(target, {
theme: 'tomato',
})
Or using scoped style
<template>
<div>
<button
v-tippy="{
content: 'Hi!',
appendTo: 'parent',
theme: 'tomato',
arrow: false
}"
>
Hello!
</button>
</div>
</template>
<script>
export default {}
</script>
<style scoped>
* >>> .tippy-box[data-theme~='tomato'] {
background-color: tomato;
color: yellow;
}
</style>
~=
?
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 placement
prop 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.
import { roundArrow } from 'vue-tippy'
useTippy(target, {
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:
import { roundArrow } from 'vue-tippy'
useTippy(target, {
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.