Hover Card
A floating preview that opens on hover — profile peeks, link previews, glossary terms — with the neobrutalist borders-and-shadows treatment.
import {
Avatar,
AvatarFallback,The hover card floats a panel of rich preview content over the page when the pointer rests on a trigger — no click required. Built on the Base UI Preview Card primitive and styled to the neobrutalist recipe: thick borders, hard shadows, and bold type.
Reach for it when:
- Profile peeks — hover a @mention or avatar to show the bio, stats, and a follow button.
- Link previews — surface a page's title and summary before the reader commits to the click.
- Glossary terms — define jargon inline in docs without navigating away.
Installation#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/hover-card.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/hover-card.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/hover-card.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/hover-card.json
Install the following dependencies:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
Copy and paste the following code into your project.
"use client"
import * as React from "react"
import { HoverCard as HoverCardPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function HoverCard({
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
}
function HoverCardTrigger({
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
return (
<HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
)
}
function HoverCardContent({
className,
align = "center",
sideOffset = 4,
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
return (
<HoverCardPrimitive.Portal data-slot="hover-card-portal">
<HoverCardPrimitive.Content
data-slot="hover-card-content"
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded border-2 bg-popover p-2.5 text-sm text-popover-foreground shadow-md outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className
)}
{...props}
/>
</HoverCardPrimitive.Portal>
)
}
export { HoverCard, HoverCardTrigger, HoverCardContent }
Update the import paths to match your project setup.
Usage#
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card"<HoverCard>
<HoverCardTrigger>Hover</HoverCardTrigger>
<HoverCardContent>
The React Framework – created and maintained by @vercel.
</HoverCardContent>
</HoverCard>Composition#
Use the following composition to build a HoverCard:
HoverCard
├── HoverCardTrigger
└── HoverCardContentTrigger Delays#
Use delay and closeDelay on the trigger to control when the card opens and
closes.
<HoverCard>
<HoverCardTrigger delay={100} closeDelay={200}>
Hover
</HoverCardTrigger>
<HoverCardContent>Content</HoverCardContent>
</HoverCard>Positioning#
Use the side and align props on HoverCardContent to control placement.
<HoverCard>
<HoverCardTrigger>Hover</HoverCardTrigger>
<HoverCardContent side="top" align="start">
Content
</HoverCardContent>
</HoverCard>Examples#
Basic#
import {
Avatar,
AvatarFallback,Sides#
import { Button } from "@/components/ui/button"
import {
HoverCard,RTL#
To enable RTL support in Neobrutalism.com, see the RTL configuration guide.
"use client"
import {Accessibility#
Hover cards have no dedicated WAI-ARIA pattern — the closest analogue is the Tooltip pattern. The Base UI primitive opens the card on keyboard focus of the trigger and dismisses it with Escape. Still, treat the content as supplemental for sighted users and keep the trigger a real link so the full content stays reachable at its destination.
Keyboard interactions:
| Key | Action |
|---|---|
Tab / Shift + Tab | Move focus to the trigger — focusing opens the card, leaving closes it |
Escape | Close the card |
Enter | Follow the trigger link |
API Reference#
See the Base UI documentation for more information.