Astryx Popover vs HoverCard vs Tooltip: Interaction Patterns Explained
The Astryx Tooltip and HoverCard components are both hover-triggered overlays built on the same low-level Popover API, but they differ in interactivity, timing, and UX purpose: Tooltips show brief, non-interactive hints with a default 200ms delay, while HoverCards display rich, interactive content immediately and stay open during user interaction.
Astryx provides three related but distinct primitives for contextual overlays in the @astryxdesign/core library. Understanding the interaction patterns of Popover, HoverCard, and Tooltip components ensures you select the right tool for your interface—whether you need a lightweight hint, an interactive preview, or a fully controlled overlay.
The Foundation: Shared Popover API
All three components rely on the same underlying Popover architecture for positioning and rendering. In packages/core/src/Popover/Popover.tsx, the core API handles CSS-anchor positioning, portal management, and layer stacking through packages/core/src/Layer/useLayer.tsx. This shared foundation guarantees consistent performance and accessibility across the ecosystem.
The Popover serves as the low-level primitive. Tooltip and HoverCard wrap this primitive with specialized hooks—useTooltip and useHoverCard—that implement distinct interaction patterns for different use cases.
Tooltip: Lightweight, Non-Interactive Hints
The Tooltip component in packages/core/src/Tooltip/Tooltip.tsx is designed for concise, informational text that requires no user action.
Trigger and Timing Behavior
- Delay: Opens after 200ms hover delay by default (configurable)
- Dismiss: Closes immediately when cursor leaves (or after optional
hideDelay) - Focus support: Appears on keyboard focus for accessibility
Content and ARIA Pattern
Tooltip content is plain text only—no buttons, links, or inputs. The trigger receives aria-describedby pointing to the tooltip text, creating an accessible description relationship without focus management complexity.
import {Tooltip} from '@astryxdesign/core/Tooltip';
import {Button} from '@astryxdesign/core/Button';
<Tooltip content="Save your changes" placement="above">
<Button>Save</Button>
</Tooltip>
Visual Treatment
Tooltips render with a dark background and light text. An optional hover indication (dashed underline) can appear on the trigger element to signal that additional information is available.
HoverCard: Rich, Interactive Previews
The HoverCard component in packages/core/src/HoverCard/HoverCard.tsx supports complex, interactive content that users may want to engage with.
Trigger and Timing Behavior
- No default delay: Opens immediately on hover or focus
- Persistent state: Stays open while cursor hovers either the trigger or the card itself
- Safe area: Includes buffer zones to prevent accidental dismissal during traversal
Content and ARIA Pattern
HoverCards can contain any interactive elements—buttons, links, avatars, forms. The component manages focus trapping and keyboard navigation while open. It also uses aria-describedby, but the described element is an interactive layer that may itself receive focus.
import {HoverCard} from '@astryxdesign/core/HoverCard';
import {Avatar} from '@astryxdesign/core/Avatar';
import {Button} from '@astryxdesign/core/Button';
<HoverCard
content={
<div style={{padding: 12}}>
<Avatar src="/me.jpg" size="large" />
<p>Jane Doe – Product Designer</p>
<Button>Message</Button>
</div>
}
placement="below"
>
<span style={{textDecoration: 'underline'}}>Jane</span>
</HoverCard>
Visual Treatment
HoverCards have customizable styling with no built-in hover indication—the card's visual presence alone provides affordance. This flexibility supports profile previews, mini-menus, and rich media cards.
Key Implementation Differences
| Aspect | Tooltip | HoverCard |
|---|---|---|
| Hook location | packages/core/src/Tooltip/useTooltip.tsx |
packages/core/src/HoverCard/useHoverCard.tsx |
| Default delay | 200ms | 0ms (none) |
| Dismiss behavior | On cursor exit | On cursor exit from both trigger and card |
| Interactive content | Not supported | Fully supported |
| Focus management | Minimal (describedby only) | Full navigation handling |
| Typical use | Inline help, icon labels | Profile cards, quick actions |
When to Use Each Component
Choose based on content interactivity and user intent:
-
Tooltip: Use for brief explanations of UI elements—button purposes, icon meanings, validation hints. Keep text under 60 characters.
-
HoverCard: Use for rich previews that merit user investment—profile cards with contact actions, definition popups with related links, or tool palette summaries.
-
Popover (direct): Use when you need manual control over open/close state, click triggers, or complex positioning logic that the higher-level abstractions don't support.
Summary
- Tooltip and HoverCard both extend the core Popover API with specialized interaction patterns
- Tooltip prioritizes speed and simplicity: delayed opening, quick dismissal, non-interactive content
- HoverCard prioritizes engagement: immediate opening, persistent state during interaction, full content flexibility
- Both share positioning infrastructure via
useLayerinpackages/core/src/Layer/useLayer.tsx - Select components based on whether users need to read (Tooltip) or interact (HoverCard)
Frequently Asked Questions
Does HoverCard support the same delay configuration as Tooltip?
Yes, but the defaults differ. The useHoverCard hook accepts delay parameters, though it defaults to 0ms. The useTooltip hook in packages/core/src/Tooltip/useTooltip.tsx explicitly sets 200ms as the default. You can override either behavior through props to match your specific UX requirements.
Can I put a button inside a Tooltip?
No. Tooltips are engineered for non-interactive content only. Attempting to include focusable elements violates the Astryx component contract and produces accessibility warnings. For interactive content, use HoverCard or the base Popover component with manual state control.
Do both components work with keyboard navigation?
Yes, but differently. Tooltips appear on focus and dismiss on blur without trapping focus. HoverCards implement focus management—when opened via keyboard, focus moves into the card and Tab / Shift+Tab cycle through interactive elements. The useHoverCard hook handles this automatically.
Which component should I use for a definition popup with a "Read more" link?
Use HoverCard. The presence of a clickable link makes this interactive content unsuitable for Tooltip. The HoverCard's persistent hover state lets users traverse from trigger to card without dismissal, and its focus management supports keyboard activation of the link.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →