AI CSS Animations

Guides · · Maxwell Prehoda

12 Tooltip Animation Examples That Help Without Getting in the Way

The best tooltip animations are short and directional: a fade plus a few pixels of travel away from the trigger, or a small scale that grows out of the arrow tip, finished in about 150 to 250 milliseconds. Anything longer makes the user wait for a label they wanted instantly. The other half of a good tooltip is timing you do not see: a short delay before it opens, so passing the cursor over a toolbar does not flash six labels, and no delay at all once one tooltip is already open.

Below are 12 examples worth copying, from headless libraries, pure-CSS kits, the new native browser primitives and two of our own snippets. Each one is labelled with the situation it suits, the stack it needs and the trap to avoid. Ten of the twelve are other people's work; the live demos are pure-CSS versions from our Tooltips directory that you can copy.

1. Radix UI Tooltip: Best for React design systems that need side-aware motion

Platform: React, headless, MIT license

Filter by owner or date
Live from our directory: Right Tooltip With Arrow. Copy the HTML and CSS →

Radix gives you an unstyled tooltip that handles the hard parts: it opens on hover and on keyboard focus, closes on Escape, and exposes its state to CSS. The content element carries `data-side` (top, right, bottom or left) and `data-state` (closed, delayed-open or instant-open), so you can write one keyframe per side. The docs show exactly that: a slideUp animation when the tooltip lands above the trigger and slideDown when collision detection flips it below.

The timing defaults are sensible and worth stealing even if you never use Radix: `delayDuration` is 700 ms before the first tooltip opens, and `skipDelayDuration` is 300 ms, the window in which moving to a neighbouring trigger opens its tooltip instantly. Radix also exposes a `--radix-tooltip-content-transform-origin` variable so a scale animation grows from the side that faces the trigger.

Our Right Tooltip With Arrow below is a pure-CSS version of the same origin-aware idea: the transform-origin sits on the arrow point, so the bubble grows out of the button.

Watch out for: The 700 ms default is long for icon-only toolbars where the tooltip is the only label. Shorten it there, and keep the skip window so scanning a row of icons stays fast.

Radix Primitives on GitHub ↗

2. Tippy.js animation presets: Best for legacy jQuery or vanilla sites already on Tippy

Platform: JavaScript on Popper, MIT license, v6

Share with your team
Live from our directory: Top Tooltip With Arrow. Copy the HTML and CSS →

Tippy.js was the default tooltip library for years, and its animation page is still one of the clearest catalogues of tooltip motion. The default is an opacity fade. You can import `shift-away`, `shift-toward`, `scale` and `perspective` as separate CSS files, each with `subtle` and `extreme` variants, so you can compare how far a tooltip should travel by swapping one class.

Two extras are worth knowing. `inertia: true` adds an elastic overshoot that the docs describe as a CSS-only approximation of spring physics, and the `animateFill` plugin floods the tooltip from a circular backdrop, the Material-style fill effect that was everywhere around 2017.

Our Top Tooltip With Arrow below is the pure-CSS equivalent of Tippy's shift-away: it fades in while rising a few pixels away from the trigger.

Watch out for: The GitHub repository was archived by its owner on 9 November 2024 and is read-only. Fine for an existing site, but pick something maintained for a new build.

Archived repository ↗

3. Floating UI useTransitionStyles: Best for custom React tooltips with precise positioning

Platform: React hooks, MIT license

You're all caught up
Live from our directory: Bounce In Tooltip. Copy the HTML and CSS →

Floating UI is the positioning engine many newer libraries sit on, and its transition hooks solve the problem that trips up hand-built tooltips: animating out before the element unmounts. `useTransitionStyles` returns an `isMounted` flag and a style object, defaulting to an opacity fade over 250 ms. You can pass separate `open` and `close` durations and an `initial` style, and every option can be a function of the final `side` and `placement`.

That last part is what makes tooltip motion feel right. The docs map each side to its opposite for `transformOrigin`, and recommend putting the origin on the arrow tip when you scale, using the data from the arrow middleware. If you would rather write CSS, `useTransitionStatus` just gives you a status string (`initial`, `open`, `close`) to put in a `data-status` attribute.

Our Bounce In Tooltip below shows why the arrow-tip origin matters: the scale is anchored at the arrow, so the bounce lands on the bell instead of drifting sideways.

Watch out for: With useTransitionStatus the CSS duration must match the hook's duration option. If they drift apart the tooltip unmounts mid-animation or lingers invisible.

4. Codrops Playful Little Tooltip Ideas: Best for playful marketing pages and editorial sites

Platform: SVG + anime.js demo, free

Add to favorites
Live from our directory: Morphing Pill Tooltip. Copy the HTML and CSS →

Manoela Ilic's 2017 Codrops piece is still the reference for tooltips with personality. The shapes are mostly SVG and anime.js animates them, with shape morphing and transforms doing the heavy lifting: bubbles that stretch out of the trigger, blobs that settle into a speech shape, text that arrives a beat after the container. The demo credits anime.js by Julian Garnier and Charming.js for splitting the text.

The useful lesson is the sequence: container first, then content. A tooltip that morphs into shape and then fades its words in reads as one gesture, where animating everything at once reads as noise. Codrops also keeps a tooltip tag with later work, including Dynamic Tooltip Reveal Animations from November 2023.

If you want the morph without a JavaScript library, our Morphing Pill Tooltip below does it in CSS: a dot stretches into a pill with an animated clip-path inset, so the text never squashes, and the label fades in after.

Watch out for: These are experiments, not components. They target pointer hover; you will need to add keyboard focus, Escape to dismiss and a reduced-motion fallback before shipping one.

Codrops tooltip tag ↗

5. Native popover="hint" with interestfor: Best for progressive enhancement with no tooltip library

Platform: HTML + CSS, Chromium (Chrome 133 and 142)

Monthly budget Spending pauses when you reach this limit. You can raise it at any time.
Live from our directory: Info Icon Tooltip. Copy the HTML and CSS →

The platform is finally growing a real tooltip. Chrome 133 added `popover="hint"`, a popover mode for ephemeral UI: hint popovers close on an outside click or Escape and only force-hide other hints, so opening a tooltip no longer closes the menu it sits in. Chrome 142 added the `interestfor` attribute on buttons and links, which opens the target on hover, on keyboard focus or on a long press on touchscreens, with no script.

Chrome's guide pairs the two with CSS anchor positioning: the trigger becomes an implicit anchor, so `position-area: top` with `position-try-fallbacks: flip-block` places the tooltip and flips it when it would leave the viewport. The browser adds the tooltip role and the `aria-describedby` link itself, and the guide says not to set them by hand.

Animate it the way you animate any popover: transition opacity and transform, and use `@starting-style` for the entry state. Our Info Icon Tooltip below is the hover-and-focus CSS version you can ship today while support spreads.

Watch out for: This is Chromium-first. Elsewhere you need the polyfills Chrome's guide links, and the anchor positioning polyfill does not support implicit anchors or position-area.

Chrome blog: popover=hint ↗MDN: using anchor positioning ↗

6. Hint.css by Kushagra Gour: Best for static sites and docs with zero JavaScript

Platform: Pure CSS, free

Download PDF · 2.4 MB
Live from our directory: Bottom Tooltip With Arrow. Copy the HTML and CSS →

Hint.css is a tooltip library that is only a stylesheet. You add a class such as `hint--bottom` and put the text in `aria-label` or `data-hint`, and the tooltip is drawn by pseudo-elements. It ships eight positions (four sides and four corners), four sizes, colour modifiers for error, info, warning and success, and a `hint--bounce` class that swaps the plain slide for a bouncy entrance.

It is a good example of how far CSS gets you for simple labels: no positioning engine, no portal, no JavaScript bundle. The trade is that the tooltip cannot flip when it runs into the edge of the screen, so you choose a side that always fits.

Our Bottom Tooltip With Arrow below is the same pseudo-element idea with an outlined arrow that keeps the border.

Watch out for: Pseudo-element tooltips cannot be hovered, selected or reached by a screen reader as separate content, and they clip at the viewport edge. Keep them to short labels.

GitHub ↗

7. Balloon.css by Claudio Holanda: Best for adding tooltips with one data attribute

Platform: Pure CSS, free

Start from a blank page
Live from our directory: Left Tooltip With Arrow. Copy the HTML and CSS →

Balloon.css takes the same pure-CSS approach with a different API: the tooltip text lives in `aria-label`, `data-balloon-pos` picks one of eight positions, and `data-balloon-length` sets the width from small to fit. Tooltips stay on one line unless you set a length, which is the right default for labels.

What makes it a good reference is the escape hatch: add `data-balloon-blunt` and the animation is gone. Every tooltip system should have that switch, because some contexts (dense data tables, repeated hovers in a toolbar) are better with an instant label than a moving one.

Our Left Tooltip With Arrow below shows the side placement with the classic CSS border triangle for the arrow.

Watch out for: The blunt switch is per element. For users who ask for less motion you still need a prefers-reduced-motion rule that removes the travel globally.

GitHub ↗

8. GitHub Primer Tooltip: Best for icon-only buttons in dense product UI

Platform: React and Rails components, MIT license

Ships main to production
Live from our directory: Tooltip With Delay. Copy the HTML and CSS →

Primer is the design system behind github.com, and its tooltip guidance is unusually blunt: tooltips should be a last resort for conveying information, because they are hidden by default. Its component splits tooltips into two types, `label` for naming the element (the icon-only button case) and `description` for supplementary information, which maps directly onto `aria-labelledby` versus `aria-describedby`.

The delay prop is the part to copy. Primer offers three named delays: short at 50 ms (the default), medium at 400 ms and long at 1200 ms. Naming them stops every team inventing its own number, and the short default reflects a product where tooltips label icons people need to identify quickly.

Our Tooltip With Delay below makes the wait visible: a thin bar fills under the button for half a second before the tooltip shows, and it hides at once.

Watch out for: A label tooltip replaces the button's accessible name. If the tooltip text and the visible icon disagree, voice control users will say a name that does not match what they see.

9. Ariakit Tooltip: Best for accessible-first tooltips that never act as labels

Platform: React, headless, MIT license

Pages load from a CDN CDN nounA network of servers that keeps copies of your files close to your visitors. near you.
Live from our directory: Definition Tooltip on Underlined Text. Copy the HTML and CSS →

Ariakit takes the opposite position to Primer's label type: its tooltips are non-critical visual descriptions and should not be used as the accessible label for the anchor. The anchor needs its own name from visible text, visually hidden text, `aria-label` or `aria-labelledby`, and it should be a real button or link so screen readers announce it on focus.

That rule shapes the animation too. If the tooltip carries nothing essential, it can afford a little more character, because nobody depends on reading it the instant it appears. Ariakit's own animation example uses Motion for the enter and exit.

Our Definition Tooltip on Underlined Text below is a description in exactly that sense: the term is readable without it, and the card rises while the dotted underline draws solid.

Watch out for: Do not put links or buttons inside a hover tooltip. Use a popover or hovercard that opens on click for anything interactive.

10. Bootstrap 5 tooltips: Best for Bootstrap sites that want a safe fade

Platform: JavaScript + Popper, MIT license

Not ready to publish Cover image Add a title
Live from our directory: Tooltip on Disabled Button. Copy the HTML and CSS →

Bootstrap's tooltip is the conservative baseline: a CSS fade controlled by the `animation` option (on by default), positioned by Popper, and tied to the `prefers-reduced-motion` media query through Bootstrap's reduced motion rules. Tooltips are opt-in, so you initialise them yourself, and the `delay` option takes separate show and hide values such as 500 and 100 ms.

The docs are worth reading for two edge cases most tooltip pages skip. Disabled elements cannot be hovered or focused, so they never trigger a tooltip; Bootstrap tells you to put it on a focusable wrapper instead. And tooltips on hidden elements simply do not work.

Our Tooltip on Disabled Button below handles that first case in CSS: it explains why the button is disabled with a checklist of what is missing, and the lock gives a small shake.

Watch out for: Bootstrap 5 needs Popper, either as a separate script or through bootstrap.bundle.min.js, and every tooltip must be hidden before its trigger is removed from the DOM.

11. Our Sliding Toolbar Tooltip: Best for editor toolbars with many icon buttons

Platform: Motions directory, free, pure CSS Ours

Live from our directory: Sliding Toolbar Tooltip. Copy the HTML and CSS →

One tooltip for the whole toolbar instead of one per button. It glides under whichever button you hover or focus while its label rolls to the new name, which is the behaviour Radix approximates with its skip-delay window, done as a single moving element. `:has()` sets an `--x` index for each button, and the labels are a clipped strip that slides to the right word.

Pick it for rich text editors, canvas tools and media controls, where people sweep across a row of icons and a fresh fade on every button would flicker. The shared element makes the row feel like one control.

Watch out for: It relies on :has(), which is in all current evergreen browsers. Keep each button's own accessible name, since the moving tooltip is marked aria-hidden.

12. Our Keyboard Shortcut Tooltip: Best for power-user apps that teach shortcuts

Platform: Motions directory, free, pure CSS Ours

Quick search ⌘K
Live from our directory: Keyboard Shortcut Tooltip. Copy the HTML and CSS →

A tooltip that shows the action's keyboard shortcut as keycaps, and the keys press down one after the other as it opens. It uses real `kbd` elements with an `--i` index for the stagger, so the sequence reads in the order you would press it.

This is the most useful job a tooltip can do in a productivity app: it answers what the button does and how to skip the button next time. The press animation is small enough to stay out of the way but gives the shortcut a moment of attention.

Browse the rest of the Tooltips directory for 30 variants, including copy to clipboard, form errors and link previews, each with a reduced-motion guard.

Watch out for: Show the shortcut for the user's platform (Cmd on macOS, Ctrl elsewhere). A wrong modifier key is worse than no shortcut at all.

How to choose a tooltip animation

Match it to the job the tooltip does

If the tooltip is the only name an icon has (Primer's label type), it must appear fast and plainly: a 150 ms fade with a few pixels of travel, like Tippy's shift-away or our Top Tooltip With Arrow. If it adds detail to something already readable (Ariakit's description), you can afford a richer entrance like the definition card. If it explains something people only see once, such as an onboarding hint, personality like the Codrops morphs is fine.

Match it to your stack

React design system: Radix or Floating UI, with the side-aware keyframes shown above. No JavaScript at all: Hint.css, Balloon.css or a snippet from our Tooltips directory. A new build that can lean on the platform: popover="hint" with interestfor in Chromium, with a polyfill or a plain CSS fallback elsewhere. Avoid starting new work on Tippy.js now that its repository is archived.

Match it to how often people see it

Motion that is charming once becomes friction on the fiftieth hover. In toolbars and data tables, keep the animation short, add a delay before the first open and skip it for the next one (Radix's 700 ms and 300 ms are a starting point), or use one shared tooltip like our Sliding Toolbar. Whatever you pick, meet WCAG 1.4.13: the tooltip must be dismissible with Escape, hoverable without vanishing, and persistent until the user moves away.

Ship a better tooltip today

Start with the plain version: a fade and 4 to 6 pixels of travel away from the trigger, 150 to 200 ms in, faster out, an open delay for the first tooltip in a group, Escape to close, and no motion under prefers-reduced-motion. That already beats most tooltips on the web. Then add one deliberate detail that fits the product, such as a scale from the arrow tip, a shared toolbar tooltip or a keycap press.

Copy any of the demos above from the Tooltips directory, or describe the tooltip you need and get production-ready CSS keyframes from the creator. For the wider picture of small interface motion, see our micro-interaction examples and the post on CSS animations for microinteractions.

A prompt to start from
Make a pure CSS tooltip for an icon-only button in a dark editor toolbar.
It opens on hover and keyboard focus after a 300 ms delay and closes instantly on mouse out or Escape.
Animate opacity and a 6px rise with scale from 0.96, transform-origin on the arrow tip, 180 ms ease-out in and 100 ms out.
Show the keyboard shortcut as kbd keycaps on the right of the label.
Under prefers-reduced-motion, keep only the opacity fade.

Make your own with AI →

Common questions

How do you animate a tooltip with CSS only?

Keep the tooltip in the DOM with opacity 0, visibility hidden and a small translate, then on :hover and :focus-within of the trigger transition it to opacity 1, visibility visible and no translate. Transition visibility as well as opacity so the hidden tooltip cannot be hovered. Use transition-delay on the open state only if you want an open delay without a close delay.

How long should a tooltip animation be?

Around 150 to 250 ms for the entrance and less for the exit. Floating UI's default transition is 250 ms. The delay before the first tooltip opens is a separate number: Radix uses 700 ms by default, Primer's default is 50 ms for icon labels, and Bootstrap lets you set show and hide delays separately.

Should a tooltip open on focus as well as hover?

Yes. Keyboard users need the same information, and WCAG 1.4.13 (Content on Hover or Focus, level AA) requires that content shown on hover or focus can be dismissed without moving focus, can be hovered without disappearing, and stays visible until the user moves away or dismisses it.

Is there a native HTML tooltip element?

Not a dedicated element, but Chromium now has the pieces: popover="hint" (Chrome 133) for ephemeral popovers, the interestfor attribute (Chrome 142) to open them on hover, focus or long press, and CSS anchor positioning to place them. Other browsers need polyfills for now. The title attribute is not a good tooltip: it cannot be styled or animated and does not show on keyboard focus.

Why does my tooltip flicker when I move along a toolbar?

Each button opens and closes its own tooltip with a full delay and animation. Add a skip window so the next tooltip opens instantly while one is already showing, or use a single shared tooltip that moves between buttons, like our Sliding Toolbar Tooltip.

Sources