Components/Hover Card

Hover Card

Three components: the trigger through five states, the card as an empty slot, and the pair together with the card hanging off the trigger as an absolute child.

Hover Card · Components frameLive in the browser · drawn to match the file
Active
@nextjs
Your content goes here
Active=Yes74 × 32 in the file · card 256 × 100 at +40
the board never grows

Active=Yes stays 74 × 32. The card is an absolute child sitting 40 below with clipping switched off, so opening one does not push the sentence it is sitting in around, which is exactly how it behaves on a page.

the card is a slot

256 × 100 with 16 of padding and a base.muted rectangle inside saying "Your content goes here". It is published on its own so you can drop an avatar, a paragraph or a stat row in without the Hover Card needing a variant for each.

shadow-md, exactly

Two drop shadows: 0 4 6 at -1 spread, and 0 2 4 at -2, both black at 10%. That is Tailwind's shadow-md transcribed rather than approximated, which is why it sits at the same depth as every other floating surface in the kit.

The trigger

Five states, and only one of them adds a colour

A hover card trigger is a piece of running text, not a control, so most of its states change the type rather than the surface: hover underlines it, pressed drops it to base.muted-foreground, disabled takes the whole thing to 50%. Only focus paints anything.

Hover Card / Trigger · Components frameLive in the browser · drawn to match the file
State
@nextjs
State=Hover94 × 32 in the file
DefaultNothing. base.foreground at 14/500.
HoverThe text underlines. No fill, no border.
FocusA 3px base.ring outside plus a 1px base.border inside.
DisabledThe whole trigger drops to 50% opacity.
PressedThe text goes to base.muted-foreground.
The usage frame

A handle and a link, both mid-sentence

824 by 788. The same handle closed and then open, a column of all five trigger states, and a link inside body copy. Both open cards have the base.muted slot cleared so the text sits straight on the popover.

Section
Built with @nextjs and deployed on Vercel.
The React framework for the web - used by Vercel, Netflix and Notion.
In the file

Three components, seven variants

Read straight out of the Penpot file. The axes below are the property names you will see in the variant dropdown.

Hover Card / TriggerStateDefault · Hover · Focus · Disabled · Pressed - 94 × 325
Hover CardActiveNo · Yes - 74 × 32 either way; the card is absolute2
Hover Card / Cardnone256 × 100 - a base.muted slot on 16 of padding1

Using the Hover Card

Because the card is an absolute child sitting 40 below the trigger, with clipping switched off on the board. Opening one does not reflow the sentence it lives in, which is what happens on a real page: a hover card floats over the text rather than pushing it apart.

So it can be filled. It ships as 256 × 100 with a base.muted rectangle inside saying "Your content goes here", and the usage frame clears that fill and drops copy straight onto the popover. An avatar, a paragraph or a stat row all fit without the Hover Card needing a variant for each.

Because the trigger is running text, not a control. Hover underlines it, pressed drops it to base.muted-foreground, disabled takes the whole thing to 50%. Only focus paints anything: a 3px base.ring outside plus a 1px base.border inside, the same ring every other focusable thing in the kit gets.

Tailwind's shadow-md, transcribed rather than approximated: 0 4 6 at -1 spread and 0 2 4 at -2, both black at 10%. That puts it at the same depth as the other floating surfaces instead of at a hand-picked one.

Overlays · 7 variants