Tooltip
A small popup that appears when a user hovers over or focuses an element.
Examples
Positioning
Use positionerProps on TooltipContent to control which side the tooltip appears on.
Hover delay
Control the open delay with the delay prop on TooltipTrigger.
Animated shared tooltip
Use createTooltipHandle with TooltipProvider to share a single tooltip across multiple triggers. The TooltipViewport component animates the content when moving between triggers.
Installation
Copy the source code below into your project:
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
import { cn } from "@/lib/utils";
const createTooltipHandle = BaseTooltip.createHandle;
function Tooltip({ children, ...props }: BaseTooltip.Root.Props) {
return (
<BaseTooltip.Root data-slot="tooltip" {...props}>
{children}
</BaseTooltip.Root>
);
}
function TooltipProvider({ ...props }: BaseTooltip.Provider.Props) {
return <BaseTooltip.Provider data-slot="tooltip-provider" {...props} />;
}
function TooltipTrigger({ delay = 100, ...props }: BaseTooltip.Trigger.Props) {
return <BaseTooltip.Trigger delay={delay} data-slot="tooltip-trigger" {...props} />;
}
function TooltipContent({
className,
children,
positionerProps,
portalProps,
...props
}: BaseTooltip.Popup.Props & {
positionerProps?: BaseTooltip.Positioner.Props;
portalProps?: BaseTooltip.Portal.Props;
}) {
return (
<BaseTooltip.Portal {...portalProps}>
<BaseTooltip.Positioner
alignOffset={positionerProps?.alignOffset || 0}
className={cn(
"outline-none",
"h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom,transform] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-instant:transition-none",
positionerProps?.className,
)}
side={positionerProps?.side || "top"}
sideOffset={positionerProps?.sideOffset || 4}
{...positionerProps}
>
<BaseTooltip.Popup
className={cn(
"flex h-(--popup-height,auto) w-(--popup-width,auto) origin-(--transform-origin) flex-col rounded-lg bg-gray-900 px-3 py-2 text-sm text-gray-50 transition-[transform,scale,opacity] data-ending-style:scale-90 data-ending-style:opacity-0 data-instant:duration-0 data-starting-style:scale-90 data-starting-style:opacity-0 dark:outline dark:-outline-offset-1 dark:outline-gray-700",
className,
)}
data-slot="tooltip-popup"
{...props}
>
{children}
</BaseTooltip.Popup>
</BaseTooltip.Positioner>
</BaseTooltip.Portal>
);
}
function TooltipViewport({
children,
className: _className,
...props
}: BaseTooltip.Viewport.Props) {
return (
<BaseTooltip.Viewport
className="relative h-full w-full overflow-clip px-(--viewport-inline-padding) py-1 [--viewport-inline-padding:0.5rem] **:data-current:w-[calc(var(--popup-width)-2*var(--viewport-inline-padding))] **:data-current:translate-x-0 **:data-current:opacity-100 **:data-current:transition-[translate,opacity] **:data-current:duration-[350ms,175ms] **:data-current:ease-[cubic-bezier(0.22,1,0.36,1)] **:data-previous:w-[calc(var(--popup-width)-2*var(--viewport-inline-padding))] **:data-previous:translate-x-0 **:data-previous:opacity-100 **:data-previous:transition-[translate,opacity] **:data-previous:duration-[350ms,175ms] **:data-previous:ease-[cubic-bezier(0.22,1,0.36,1)] data-[activation-direction~='left']:[&_[data-current][data-starting-style]]:-translate-x-1/2 data-[activation-direction~='left']:[&_[data-current][data-starting-style]]:opacity-0 data-[activation-direction~='right']:[&_[data-current][data-starting-style]]:translate-x-1/2 data-[activation-direction~='right']:[&_[data-current][data-starting-style]]:opacity-0 data-[activation-direction~='left']:[&_[data-previous][data-ending-style]]:translate-x-1/2 data-[activation-direction~='left']:[&_[data-previous][data-ending-style]]:opacity-0 data-[activation-direction~='right']:[&_[data-previous][data-ending-style]]:-translate-x-1/2 data-[activation-direction~='right']:[&_[data-previous][data-ending-style]]:opacity-0 [[data-instant]_&_[data-current]]:transition-none [[data-instant]_&_[data-previous]]:transition-none"
data-slot="tooltip-viewport"
{...props}
>
{children}
</BaseTooltip.Viewport>
);
}
export {
Tooltip,
TooltipProvider,
TooltipTrigger,
TooltipContent,
TooltipViewport,
createTooltipHandle,
};API Reference
Tooltip
This component does not add any props on top of Base UI Tooltip.Root. See the Base UI docs for the full API reference.
TooltipTrigger
The TooltipTrigger component extends the Base UI Tooltip.Trigger props and adds the following:
| Prop | Type | Default | Description |
|---|---|---|---|
| delay | number | 100 | Delay in milliseconds before the tooltip opens. |
TooltipContent
The TooltipContent component extends the Base UI Tooltip.Popup props and adds the following:
| Prop | Type | Default | Description |
|---|---|---|---|
| positionerProps | BaseTooltip.Positioner.Props | - | Props forwarded to the underlying Positioner component. Includes align, side, sideOffset, alignOffset, collisionPadding, etc. |
| portalProps | BaseTooltip.Portal.Props | - | Props forwarded to the underlying Portal component. |
TooltipViewport
This component does not add any props on top of Base UI Tooltip.Viewport. See the Base UI docs for the full API reference.
TooltipProvider
This component does not add any props on top of Base UI Tooltip.Provider. See the Base UI docs for the full API reference.