# Hover Card

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
---

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="outline">@starwind</Button>
  </HoverCardTrigger>
  <HoverCardContent class="w-80" align="start">
    <div class="flex justify-between gap-4">
      <Avatar class="shrink-0">
        <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
        <AvatarFallback>SW</AvatarFallback>
      </Avatar>
      <div class="space-y-1">
        <h4 class="text-sm font-semibold">Starwind UI</h4>
        <p class="text-muted-foreground text-sm">
          Accessible Astro components styled with Tailwind CSS.
        </p>
        <span class="text-muted-foreground block pt-2 text-xs">Built for Astro developers</span>
      </div>
    </div>
  </HoverCardContent>
</HoverCard>
```
  </div>
  <div slot="react">
```tsx
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";

export function Example() {
  return (
    <HoverCard>
      <HoverCardTrigger asChild>
        <Button variant="outline">@starwind</Button>
      </HoverCardTrigger>
      <HoverCardContent className="w-80" align="start">
        <div className="flex justify-between gap-4">
          <Avatar className="shrink-0">
            <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
            <AvatarFallback>SW</AvatarFallback>
          </Avatar>
          <div className="space-y-1">
            <h4 className="text-sm font-semibold">Starwind UI</h4>
            <p className="text-muted-foreground text-sm">
              Accessible Astro components styled with Tailwind CSS.
            </p>
            <span className="text-muted-foreground block pt-2 text-xs">Built for Astro developers</span>
          </div>
        </div>
      </HoverCardContent>
    </HoverCard>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { ButtonVariants } from "@/components/starwind/button";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
</script>

<template>
  <HoverCard>
    <HoverCardTrigger asChild>
      <button type="button" :class="ButtonVariants.button({ variant: 'outline' })">
        @starwind
      </button>
    </HoverCardTrigger>
    <HoverCardContent class="w-80" align="start">
      <div class="flex justify-between gap-4">
        <Avatar class="shrink-0">
          <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
          <AvatarFallback>SW</AvatarFallback>
        </Avatar>
        <div class="space-y-1">
          <h4 class="text-sm font-semibold">Starwind UI</h4>
          <p class="text-muted-foreground text-sm">
            Accessible Astro components styled with Tailwind CSS.
          </p>
          <span class="text-muted-foreground block pt-2 text-xs">Built for Astro developers</span>
        </div>
      </div>
    </HoverCardContent>
  </HoverCard>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Installation

```bash
npx starwind@latest add hover-card --framework astro
```
</DocsTabsContent>
```bash
npx starwind@latest add hover-card --framework react
```
</DocsTabsContent>
```bash
npx starwind@latest add hover-card --framework vue
```
</DocsTabsContent>
</DocsTabs>

## Usage

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
---

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="outline">@starwind</Button>
  </HoverCardTrigger>
  <HoverCardContent class="w-80" align="start">
    <div class="flex justify-between gap-4">
      <Avatar class="shrink-0">
        <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
        <AvatarFallback>SW</AvatarFallback>
      </Avatar>
      <div class="space-y-1">
        <h4 class="text-sm font-semibold">Starwind UI</h4>
        <p class="text-muted-foreground text-sm">
          Accessible Astro components styled with Tailwind CSS.
        </p>
        <span class="text-muted-foreground block pt-2 text-xs">Built for Astro developers</span>
      </div>
    </div>
  </HoverCardContent>
</HoverCard>
```
  </div>
  <div slot="react">
```tsx
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";

export function Example() {
  return (
    <HoverCard>
      <HoverCardTrigger asChild>
        <Button variant="outline">@starwind</Button>
      </HoverCardTrigger>
      <HoverCardContent className="w-80" align="start">
        <div className="flex justify-between gap-4">
          <Avatar className="shrink-0">
            <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
            <AvatarFallback>SW</AvatarFallback>
          </Avatar>
          <div className="space-y-1">
            <h4 className="text-sm font-semibold">Starwind UI</h4>
            <p className="text-muted-foreground text-sm">
              Accessible Astro components styled with Tailwind CSS.
            </p>
            <span className="text-muted-foreground block pt-2 text-xs">Built for Astro developers</span>
          </div>
        </div>
      </HoverCardContent>
    </HoverCard>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { ButtonVariants } from "@/components/starwind/button";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
</script>

<template>
  <HoverCard>
    <HoverCardTrigger asChild>
      <button type="button" :class="ButtonVariants.button({ variant: 'outline' })">
        @starwind
      </button>
    </HoverCardTrigger>
    <HoverCardContent class="w-80" align="start">
      <div class="flex justify-between gap-4">
        <Avatar class="shrink-0">
          <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
          <AvatarFallback>SW</AvatarFallback>
        </Avatar>
        <div class="space-y-1">
          <h4 class="text-sm font-semibold">Starwind UI</h4>
          <p class="text-muted-foreground text-sm">
            Accessible Astro components styled with Tailwind CSS.
          </p>
          <span class="text-muted-foreground block pt-2 text-xs">Built for Astro developers</span>
        </div>
      </div>
    </HoverCardContent>
  </HoverCard>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Composition

Use a trigger and content inside the root:

```text
HoverCard
├── HoverCardTrigger
└── HoverCardContent
```

## When to Use

Use Hover Card for optional context that appears when a trigger receives hover or keyboard focus.

## Profile Preview

Use `asChild` on the trigger when you want to reuse an existing interactive component like `Button`.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
---

<div class="flex flex-wrap items-center gap-4">
  <HoverCard>
    <HoverCardTrigger asChild>
      <Button variant="outline">@starwind</Button>
    </HoverCardTrigger>
    <HoverCardContent align="start" class="w-80">
      <div class="flex justify-between gap-4">
        <Avatar class="shrink-0">
          <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
          <AvatarFallback>SW</AvatarFallback>
        </Avatar>
        <div class="space-y-1">
          <h4 class="text-sm font-semibold">Starwind UI</h4>
          <p class="text-muted-foreground text-sm">
            Accessible Astro components styled with Tailwind CSS.
          </p>
          <div class="flex items-center pt-2">
            <span class="text-muted-foreground text-xs">Built for Astro developers</span>
          </div>
        </div>
      </div>
    </HoverCardContent>
  </HoverCard>

  <HoverCard openDelay={200} closeDelay={200}>
    <HoverCardTrigger asChild>
      <Button href="https://astro.build" variant="ghost">Astro</Button>
    </HoverCardTrigger>
    <HoverCardContent side="right" align="start" class="w-80">
      <div class="space-y-2">
        <h4 class="text-sm font-semibold">Astro</h4>
        <p class="text-muted-foreground text-sm">
          A web framework for content-driven sites with fast-by-default performance.
        </p>
      </div>
    </HoverCardContent>
  </HoverCard>
</div>
```
  </div>
  <div slot="react">
```tsx
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";

export function Example() {
  return (
    <>
      <div className="flex flex-wrap items-center gap-4">
        <HoverCard>
          <HoverCardTrigger asChild>
            <Button variant="outline">@starwind</Button>
          </HoverCardTrigger>
          <HoverCardContent align="start" className="w-80">
            <div className="flex justify-between gap-4">
              <Avatar className="shrink-0">
                <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
                <AvatarFallback>SW</AvatarFallback>
              </Avatar>
              <div className="space-y-1">
                <h4 className="text-sm font-semibold">Starwind UI</h4>
                <p className="text-muted-foreground text-sm">
                  Accessible Astro components styled with Tailwind CSS.
                </p>
                <div className="flex items-center pt-2">
                  <span className="text-muted-foreground text-xs">Built for Astro developers</span>
                </div>
              </div>
            </div>
          </HoverCardContent>
        </HoverCard>

        <HoverCard openDelay={200} closeDelay={200}>
          <HoverCardTrigger asChild>
            <Button href="https://astro.build" variant="ghost">Astro</Button>
          </HoverCardTrigger>
          <HoverCardContent side="right" align="start" className="w-80">
            <div className="space-y-2">
              <h4 className="text-sm font-semibold">Astro</h4>
              <p className="text-muted-foreground text-sm">
                A web framework for content-driven sites with fast-by-default performance.
              </p>
            </div>
          </HoverCardContent>
        </HoverCard>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { ButtonVariants } from "@/components/starwind/button";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/starwind/avatar";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
</script>

<template>
  <div class="flex flex-wrap items-center gap-4">
    <HoverCard>
      <HoverCardTrigger asChild>
        <button type="button" :class="ButtonVariants.button({ variant: 'outline' })">
          @starwind
        </button>
      </HoverCardTrigger>
      <HoverCardContent align="start" class="w-80">
        <div class="flex justify-between gap-4">
          <Avatar class="shrink-0">
            <AvatarImage src="https://i.pravatar.cc/150?u=starwind" alt="Starwind UI" />
            <AvatarFallback>SW</AvatarFallback>
          </Avatar>
          <div class="space-y-1">
            <h4 class="text-sm font-semibold">Starwind UI</h4>
            <p class="text-muted-foreground text-sm">
              Accessible Astro components styled with Tailwind CSS.
            </p>
            <div class="flex items-center pt-2">
              <span class="text-muted-foreground text-xs">Built for Astro developers</span>
            </div>
          </div>
        </div>
      </HoverCardContent>
    </HoverCard>

    <HoverCard :openDelay="200" :closeDelay="200">
      <HoverCardTrigger asChild>
        <a href="https://astro.build" :class="ButtonVariants.button({ variant: 'ghost' })">Astro</a>
      </HoverCardTrigger>
      <HoverCardContent side="right" align="start" class="w-80">
        <div class="space-y-2">
          <h4 class="text-sm font-semibold">Astro</h4>
          <p class="text-muted-foreground text-sm">
            A web framework for content-driven sites with fast-by-default performance.
          </p>
        </div>
      </HoverCardContent>
    </HoverCard>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Side and Alignment

Use `side`, `align`, and `sideOffset` on `HoverCardContent` to control placement.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
---

<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
  <HoverCard openDelay={150}>
    <HoverCardTrigger asChild>
      <Button variant="outline" class="w-full">Top</Button>
    </HoverCardTrigger>
    <HoverCardContent side="top" sideOffset={8}>Appears above the trigger.</HoverCardContent>
  </HoverCard>

  <HoverCard openDelay={150}>
    <HoverCardTrigger asChild>
      <Button variant="outline" class="w-full">Right</Button>
    </HoverCardTrigger>
    <HoverCardContent side="right" align="start" sideOffset={8}>
      Appears to the right and aligns to the start.
    </HoverCardContent>
  </HoverCard>

  <HoverCard openDelay={150}>
    <HoverCardTrigger asChild>
      <Button variant="outline" class="w-full">Bottom</Button>
    </HoverCardTrigger>
    <HoverCardContent side="bottom" align="end" sideOffset={8}>
      Appears below and aligns to the end.
    </HoverCardContent>
  </HoverCard>

  <HoverCard openDelay={150}>
    <HoverCardTrigger asChild>
      <Button variant="outline" class="w-full">Left</Button>
    </HoverCardTrigger>
    <HoverCardContent side="left" sideOffset={8}>Appears to the left.</HoverCardContent>
  </HoverCard>
</div>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";

export function Example() {
  return (
    <>
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <HoverCard openDelay={150}>
          <HoverCardTrigger asChild>
            <Button variant="outline" className="w-full">Top</Button>
          </HoverCardTrigger>
          <HoverCardContent side="top" sideOffset={8}>Appears above the trigger.</HoverCardContent>
        </HoverCard>

        <HoverCard openDelay={150}>
          <HoverCardTrigger asChild>
            <Button variant="outline" className="w-full">Right</Button>
          </HoverCardTrigger>
          <HoverCardContent side="right" align="start" sideOffset={8}>
            Appears to the right and aligns to the start.
          </HoverCardContent>
        </HoverCard>

        <HoverCard openDelay={150}>
          <HoverCardTrigger asChild>
            <Button variant="outline" className="w-full">Bottom</Button>
          </HoverCardTrigger>
          <HoverCardContent side="bottom" align="end" sideOffset={8}>
            Appears below and aligns to the end.
          </HoverCardContent>
        </HoverCard>

        <HoverCard openDelay={150}>
          <HoverCardTrigger asChild>
            <Button variant="outline" className="w-full">Left</Button>
          </HoverCardTrigger>
          <HoverCardContent side="left" sideOffset={8}>Appears to the left.</HoverCardContent>
        </HoverCard>
      </div>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { ButtonVariants } from "@/components/starwind/button";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
</script>

<template>
  <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
    <HoverCard :openDelay="150">
      <HoverCardTrigger asChild>
        <button
          type="button"
          :class="ButtonVariants.button({ variant: 'outline', class: 'w-full' })"
        >
          Top
        </button>
      </HoverCardTrigger>
      <HoverCardContent side="top" :sideOffset="8">Appears above the trigger.</HoverCardContent>
    </HoverCard>

    <HoverCard :openDelay="150">
      <HoverCardTrigger asChild>
        <button
          type="button"
          :class="ButtonVariants.button({ variant: 'outline', class: 'w-full' })"
        >
          Right
        </button>
      </HoverCardTrigger>
      <HoverCardContent side="right" align="start" :sideOffset="8">
        Appears to the right and aligns to the start.
      </HoverCardContent>
    </HoverCard>

    <HoverCard :openDelay="150">
      <HoverCardTrigger asChild>
        <button
          type="button"
          :class="ButtonVariants.button({ variant: 'outline', class: 'w-full' })"
        >
          Bottom
        </button>
      </HoverCardTrigger>
      <HoverCardContent side="bottom" align="end" :sideOffset="8">
        Appears below and aligns to the end.
      </HoverCardContent>
    </HoverCard>

    <HoverCard :openDelay="150">
      <HoverCardTrigger asChild>
        <button
          type="button"
          :class="ButtonVariants.button({ variant: 'outline', class: 'w-full' })"
        >
          Left
        </button>
      </HoverCardTrigger>
      <HoverCardContent side="left" :sideOffset="8">Appears to the left.</HoverCardContent>
    </HoverCard>
  </div>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## Non-hoverable Content

By default, moving the pointer from trigger to content keeps the card open. Set `disableHoverableContent` to close immediately when leaving the trigger.

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
---

<HoverCard>
  <HoverCardTrigger asChild>
    <Button variant="outline">Hoverable content (default)</Button>
  </HoverCardTrigger>
  <HoverCardContent class="max-w-[220px]">
    You can move your pointer into this card without closing it.
  </HoverCardContent>
</HoverCard>

<HoverCard disableHoverableContent>
  <HoverCardTrigger asChild>
    <Button variant="outline">Trigger-only hover</Button>
  </HoverCardTrigger>
  <HoverCardContent class="max-w-[220px]">
    This card closes when the pointer leaves the trigger.
  </HoverCardContent>
</HoverCard>
```
  </div>
  <div slot="react">
```tsx
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";

export function Example() {
  return (
    <>
      <HoverCard>
        <HoverCardTrigger asChild>
          <Button variant="outline">Hoverable content (default)</Button>
        </HoverCardTrigger>
        <HoverCardContent className="max-w-[220px]">
          You can move your pointer into this card without closing it.
        </HoverCardContent>
      </HoverCard>

      <HoverCard disableHoverableContent>
        <HoverCardTrigger asChild>
          <Button variant="outline">Trigger-only hover</Button>
        </HoverCardTrigger>
        <HoverCardContent className="max-w-[220px]">
          This card closes when the pointer leaves the trigger.
        </HoverCardContent>
      </HoverCard>
    </>
  );
}
```
  </div>
  <div slot="vue">
```vue
<script setup lang="ts">
import { ButtonVariants } from "@/components/starwind/button";
import { Button } from "@/components/starwind/button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/starwind/hover-card";
</script>

<template>
  <HoverCard>
    <HoverCardTrigger asChild>
      <button type="button" :class="ButtonVariants.button({ variant: 'outline' })">
        Hoverable content (default)
      </button>
    </HoverCardTrigger>
    <HoverCardContent class="max-w-[220px]">
      You can move your pointer into this card without closing it.
    </HoverCardContent>
  </HoverCard>

  <HoverCard disableHoverableContent>
    <HoverCardTrigger asChild>
      <button type="button" :class="ButtonVariants.button({ variant: 'outline' })">
        Trigger-only hover
      </button>
    </HoverCardTrigger>
    <HoverCardContent class="max-w-[220px]">
      This card closes when the pointer leaves the trigger.
    </HoverCardContent>
  </HoverCard>
</template>
```
  </div>
</FrameworkCodeSwitcher>

## API Reference
### HoverCard
- Inherits div attributes.

### HoverCardTrigger
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `false` | Primitive override | Merges the component behavior and props into its child element. |
| `closeDelay` | `number` | No | - | Primitive override | Sets the delay in milliseconds before closing. |
| `openDelay` | `number` | No | - | Primitive override | Sets the delay in milliseconds before opening. |
- Inherits a attributes.

### HoverCardContent
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `disablePortal` | `boolean` | No | `false` | Wrapper prop | Keeps the public Portal wrapper inline instead of moving it to a target. |
| `portalContainer` | `string` | No | - | Wrapper prop | Sets the CSS selector for the public Portal wrapper target. |
| `positionerClass` | `string` | No | - | Wrapper prop | Adds classes to the generated floating positioner element. |
| `sideOffset` | `number` | No | `4` | Primitive override | Sets the distance in pixels between floating content and its anchor. |
- Inherits div attributes.
### Primitive And Runtime API
Behavior, state, events, form participation, and imperative methods are documented in the lower-level references.
- Primitive: [Preview Card Primitive](/docs/primitives/preview-card/)
- Runtime factory: [`createPreviewCard`](/docs/runtime/#create-preview-card) from `@starwind-ui/runtime/preview-card`

## Changelog

### v2.2.0

- Added `portalContainer` and `disablePortal` to `HoverCardContent` for custom portal targets and
inline rendering.

### v2.1.0

- Added `positionerClass` to `HoverCardContent` so the floating positioner can be styled directly.
- Moved the default stacking level from the content to the positioner.

### v2.0.2

- Named the generated aggregate default export so React and Astro tooling can identify the installed component cleanly.

### v2.0.0

- Rebuilt Hover Card on Starwind Runtime for hover and focus state, floating placement, and dismissal.
- See the [Preview Card Primitive](/docs/primitives/preview-card/) for the underlying unstyled anatomy and behavior API.