Tooltip
A tooltip component for displaying contextual labels on hover and focus
Anatomy
<Tooltip.Provider>
<Tooltip.Root>
<Tooltip.Trigger>Hover me</Tooltip.Trigger>
<Tooltip.Popup>
<Tooltip.Arrow />
Label text
</Tooltip.Popup>
</Tooltip.Root>
</Tooltip.Provider>Behavior
Displays a short label anchored to a trigger element. Opens after a configurable delay (default 600ms) on hover or immediately on focus. Closes when the pointer leaves or focus moves away, with an optional closeDelay.
The side and align props control placement relative to the trigger. Positioning uses CSS Anchor Positioning where supported, with a JavaScript measurement fallback.
The component is composed from four parts: Root manages state and context,
Trigger renders a button that activates the tooltip, Popup contains the label content,
and Arrow renders a decorative pointer. Wrap multiple tooltips in a Tooltip.Provider
to coordinate open/close timing across a group — once a tooltip becomes visible, adjacent
tooltips open instantly within the timeout window, skipping the normal delay.
Styling
Use CSS custom properties for positioning offsets:
React renders standard DOM elements. Add a className to style them:
.tooltip-popup {
--media-tooltip-side-offset: 8px;
--media-tooltip-align-offset: 0px;
}Style based on open state and transition phases:
.tooltip-popup[data-open] {
display: block;
}
.tooltip-popup[data-starting-style] {
opacity: 0;
}
.tooltip-popup[data-ending-style] {
opacity: 0;
}
.tooltip-popup[data-side="top"] {
transform-origin: bottom center;
}
.tooltip-popup[data-side="bottom"] {
transform-origin: top center;
}Accessibility
The trigger receives aria-describedby pointing to the popup when open. The popup renders with role="tooltip" and popover="manual". Tooltips open on focus and close when focus leaves, ensuring keyboard-only users can access the label.
Examples
Basic Usage
import { Tooltip } from '@videojs/react';
import './BasicUsage.css';
export default function BasicUsage() {
return (
<div className="react-tooltip-basic">
<Tooltip.Root>
<Tooltip.Trigger className="react-tooltip-basic__trigger">Hover me</Tooltip.Trigger>
<Tooltip.Popup className="react-tooltip-basic__popup">
<Tooltip.Arrow className="react-tooltip-basic__arrow" />
Tooltip content
</Tooltip.Popup>
</Tooltip.Root>
</div>
);
}
.react-tooltip-basic {
display: flex;
align-items: center;
justify-content: center;
padding: 40px 24px;
}
.react-tooltip-basic__trigger {
padding: 6px 16px;
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(10px);
color: black;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
cursor: pointer;
}
.react-tooltip-basic__popup {
--media-tooltip-side-offset: 8px;
margin: 0;
border: 0;
background: rgba(0, 0, 0, 0.85);
backdrop-filter: blur(10px);
color: white;
border-radius: 6px;
padding: 4px 10px;
font-size: 13px;
white-space: nowrap;
pointer-events: none;
}
.react-tooltip-basic__arrow {
fill: rgba(0, 0, 0, 0.85);
}
Grouping
Wrap multiple tooltips in a Tooltip.Provider to share a delay group. Once a tooltip
becomes visible, adjacent tooltips open instantly within the timeout window, skipping
the normal delay.
import { Tooltip } from '@videojs/react';
import './Grouping.css';
export default function Grouping() {
return (
<div className="react-tooltip-grouping">
<Tooltip.Provider>
<Tooltip.Root>
<Tooltip.Trigger className="react-tooltip-grouping__trigger">Play</Tooltip.Trigger>
<Tooltip.Popup className="react-tooltip-grouping__popup">
<Tooltip.Arrow className="react-tooltip-grouping__arrow" />
Play video
</Tooltip.Popup>
</Tooltip.Root>
<Tooltip.Root>
<Tooltip.Trigger className="react-tooltip-grouping__trigger">Mute</Tooltip.Trigger>
<Tooltip.Popup className="react-tooltip-grouping__popup">
<Tooltip.Arrow className="react-tooltip-grouping__arrow" />
Mute audio
</Tooltip.Popup>
</Tooltip.Root>
<Tooltip.Root>
<Tooltip.Trigger className="react-tooltip-grouping__trigger">Fullscreen</Tooltip.Trigger>
<Tooltip.Popup className="react-tooltip-grouping__popup">
<Tooltip.Arrow className="react-tooltip-grouping__arrow" />
Enter fullscreen
</Tooltip.Popup>
</Tooltip.Root>
</Tooltip.Provider>
</div>
);
}
.react-tooltip-grouping {
display: flex;
align-items: center;
justify-content: center;
padding: 40px 24px;
}
.react-tooltip-grouping__trigger {
padding: 6px 16px;
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(10px);
color: black;
border: 1px solid rgba(255, 255, 255, 0.3);
cursor: pointer;
}
.react-tooltip-grouping__popup {
--media-tooltip-side-offset: 8px;
margin: 0;
border: 0;
background: rgba(0, 0, 0, 0.85);
backdrop-filter: blur(10px);
color: white;
border-radius: 6px;
padding: 4px 10px;
font-size: 13px;
white-space: nowrap;
pointer-events: none;
}
.react-tooltip-grouping__arrow {
fill: rgba(0, 0, 0, 0.85);
}
API Reference
Provider
Props
| Prop | Type | Default | Details |
|---|---|---|---|
closeDelay | number | — | |
| |||
delay | number | — | |
| |||
timeout | number | — | |
| |||
Root
Props
| Prop | Type | Default | Details |
|---|---|---|---|
align | 'start' | 'center' | 'end' | 'center' | |
| |||
closeDelay | number | 0 | |
| |||
defaultOpen | boolean | false | |
| |||
delay | number | 600 | |
| |||
disabled | boolean | false | |
| |||
disableHoverablePopup | boolean | true | |
| |||
open | boolean | false | |
| |||
side | 'top' | 'bottom' | 'left' | 'right' | 'top' | |
| |||
State
State is accessible via the render, className, and style props.
| Property | Type | Details |
|---|---|---|
open | boolean | |
| ||
status | 'idle' | 'starting' | 'ending' | |
| ||
side | 'top' | 'bottom' | 'left' | 'right' | |
| ||
align | 'start' | 'center' | 'end' | |
| ||
transitionStarting | boolean | |
| ||
transitionEnding | boolean | |
| ||
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-open | ||
| ||
data-side | 'top' | 'bottom' | 'left' | 'right' | |
| ||
data-align | 'start' | 'center' | 'end' | |
| ||
data-starting-style | ||
| ||
data-ending-style | ||
| ||
CSS custom properties
| Variable | Details |
|---|---|
--media-tooltip-side-offset | |
| |
--media-tooltip-align-offset | |
| |
--media-tooltip-anchor-width | |
| |
--media-tooltip-anchor-height | |
| |
--media-tooltip-available-width | |
| |
--media-tooltip-available-height | |
| |
Trigger
Element that triggers the tooltip on hover and focus. Renders a <button> element.
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-open | ||
| ||
data-side | 'top' | 'bottom' | 'left' | 'right' | |
| ||
data-align | 'start' | 'center' | 'end' | |
| ||
data-starting-style | ||
| ||
data-ending-style | ||
| ||
Popup
Container for the tooltip content. Positioned relative to the trigger using CSS anchor positioning with a JavaScript fallback.
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-open | ||
| ||
data-side | 'top' | 'bottom' | 'left' | 'right' | |
| ||
data-align | 'start' | 'center' | 'end' | |
| ||
data-starting-style | ||
| ||
data-ending-style | ||
| ||
Arrow
Decorative arrow pointing from the tooltip toward the trigger. Hidden from assistive technology.