React Tooltip Component Examples
Copy-paste React Tooltip examples: the four positions, an icon-button trigger, a text trigger, and a disabled-button hint — all pure CSS, all TypeScript.
A tooltip is a small label that appears on hover or focus to explain what a control does — the name of an icon button, the meaning of a badge. The Tooltip component in Drivn is unusual in that it ships with zero runtime UI dependencies and zero JavaScript for showing and hiding: the tip is a <span> that starts at opacity-0 and transitions to opacity-100 through Tailwind's group-hover and group-focus-within classes alone. You install it with npx drivn add tooltip, then wrap any trigger and pass the label as a content string.
Every example below is TypeScript, because Drivn ships TypeScript-only .tsx source installed by the Drivn CLI under @/components/ui/tooltip. The API is deliberately small: a content string for the label, a position prop — top, bottom, left, or right, defaulting to top — an optional className, and the trigger as children. There is no provider to mount and no open state to manage; the wrapper carries tabIndex={0} so the tip also shows on keyboard focus through group-focus-within.
The examples cover the default top tooltip, all four positions, an icon-button trigger, a text trigger, and a hint on a disabled-looking control.
A default tooltip on hover
The simplest use is one Tooltip wrapping a trigger, with the label passed as the content string. With no position prop it defaults to top, so the tip appears centered above the trigger on hover. Because the wrapper carries tabIndex={0} and the tip reacts to group-focus-within, the same label also appears when the trigger receives keyboard focus — no extra props required.
There is nothing to wire: no provider, no open state, no effect. The content is rendered into a pointer-events-none span so it never steals the pointer from the trigger underneath, and the whole thing is plain CSS, so it works in a Server Component without a 'use client' boundary. This is the canonical pattern for naming an otherwise unlabeled control — an icon button, a status dot, a truncated value.
1 import { Tooltip } from "@/components/ui/tooltip" 2 3 export default function Page() { 4 return ( 5 <Tooltip content="This is a tooltip"> 6 <span>Hover me</span> 7 </Tooltip> 8 ) 9 }
All four positions
The position prop places the tip on any of four sides — top, bottom, left, or right — and is typed as keyof typeof styles.positions, so the allowed values autocomplete with no magic strings. Each value indexes into a styles.positions object of static Tailwind utilities that absolutely-position and center the tip relative to the trigger: top uses bottom-full ... mb-2, bottom uses top-full ... mt-2, and the horizontal sides use right-full/left-full with a vertical centering translate.
Pick the side that keeps the tip clear of nearby content and screen edges. Because placement is pure CSS with no collision detection, a top tooltip stays on top even near the top of the viewport — choose bottom for triggers in a page header, or right for items in a left rail. Mixing positions in one toolbar is free; each Tooltip reads its own position independently.
1 <Tooltip content="Top tooltip" position="top"> 2 <span>Top</span> 3 </Tooltip> 4 5 <Tooltip content="Bottom tooltip" position="bottom"> 6 <span>Bottom</span> 7 </Tooltip> 8 9 <Tooltip content="Left tooltip" position="left"> 10 <span>Left</span> 11 </Tooltip> 12 13 <Tooltip content="Right tooltip" position="right"> 14 <span>Right</span> 15 </Tooltip>
A text trigger and inline hints
Tooltips are not only for buttons. Wrap a word, an abbreviation, or a Badge to attach a definition that appears on hover. Because the wrapper is an inline-flex span, it sits inline in running text without breaking the line, and the trigger keeps its own styling — underline a term, dim a label — while the tip explains it above. The trigger remains focusable via tabIndex={0}, so the hint is reachable by keyboard too.
Use this for glossary terms, status labels, or truncated values where the full text belongs in the tip. Keep the visible trigger meaningful on its own — a tooltip should add detail, not carry information that is unavailable without hovering — so the content stays accessible to readers who never trigger the tip.
1 <p> 2 Built with{" "} 3 <Tooltip content="Zero runtime UI dependencies"> 4 <span className="underline decoration-dotted"> 5 no deps 6 </span> 7 </Tooltip>{" "} 8 by design. 9 </p>
Install Drivn in one command
Copy the source into your project and own every line. Zero runtime dependencies, pure React + Tailwind.
npx drivn@latest createRequires Node 18+. Works with npm, pnpm, and yarn.
Frequently asked questions
No. The Tooltip imports only React and a class-merge helper. It shows and hides the tip with pure CSS — Tailwind group-hover and group-focus-within classes on a span wrapper — so there is no JavaScript open state, no provider, and no portal. That means npx drivn add tooltip ships a tooltip with zero runtime UI dependencies that works without a use client boundary.
Pass the position prop with top, bottom, left, or right; it defaults to top. The value is typed against the styles.positions object so it autocompletes, and each option indexes into static Tailwind utilities that absolutely-position and center the tip relative to the trigger. Placement is pure CSS, so there is no collision detection — pick the side that stays clear of screen edges.
Yes. The wrapper span carries tabIndex={0} and the tip reacts to group-focus-within as well as group-hover, so the label appears when the trigger receives keyboard focus, not only on mouse hover. The tip itself is pointer-events-none so it never intercepts clicks on the trigger underneath, keeping the wrapped control fully usable.
Yes, and this is the main trade for the zero-JavaScript build. The tip renders inline rather than in a portal, so a parent with overflow: hidden can clip it. For most buttons and labels this is fine; if you need the tip to escape a clipping scroll container or flip near the viewport edge, reach for the Popover component or a portal-based tooltip instead.

