Hover Card <mv-hover-card>

Carte d’aperçu enrichie au survol ou au focus clavier, avec délais d’ouverture et de fermeture et un pont invisible qui la garde ouverte pendant que le pointeur la rejoint.

CatégorieSuperpositions
TypeWeb Component (<mv-hover-card>)
Statutstable
Installe aussipopover
Keywordshover-card, preview, profile, mention, popover

When to use

  • A user mention or link should preview a profile or page on hover without navigating away
  • Supplementary details help desktop users but aren't needed to complete the task

Avoid when

  • The content is essential or must work on touch devices, where the card never opens → use Popover instead
  • The hint is a short plain-text label for an icon button → use Tooltip instead

Installation

node scripts/add.mjs hover-card --out ./src/marvelous

Agent IA avec le serveur MCP Marvelous UI : install_components({ slugs: ["hover-card"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Fichiers copiés (dépendances comprises) : tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/focus.js, core/motion.js, core/position.js, components/hover-card/hover-card.js, components/hover-card/hover-card.css, components/popover/popover.js, components/popover/popover.css.

Utilisation

Balisage de référence : partez de celui-ci et personnalisez-le avec les attributs, data-* et les variables CSS :

<div style="max-width:30rem;margin:0;text-align:center;font-size:.9375rem;line-height:1.7;color:var(--mv-fg-muted)">
  The design system was started by
  <mv-hover-card placement="bottom" arrow>
    <div data-content>
      <div style="display:flex;gap:.875rem;text-align:left">
        <span aria-hidden="true" style="flex-shrink:0;display:grid;place-items:center;width:2.75rem;height:2.75rem;border-radius:999px;background:var(--mv-accent-subtle);color:var(--mv-accent-fg);font-weight:600;font-size:.875rem">CR</span>
        <div style="display:grid;gap:.25rem;min-width:0">
          <div style="display:flex;align-items:baseline;gap:.375rem;flex-wrap:wrap">
            <strong style="color:var(--mv-fg);font-weight:600">Chloe Ramirez</strong>
            <span style="color:var(--mv-fg-subtle);font-size:.8125rem">@chloe</span>
          </div>
          <p style="margin:0;color:var(--mv-fg-muted);font-size:.8125rem;line-height:1.5">Product designer at Northwork. Obsessed with micro-interactions and 4px grids.</p>
          <div style="display:flex;gap:1rem;margin-top:.375rem;font-size:.75rem;color:var(--mv-fg-subtle)">
            <span><strong style="color:var(--mv-fg);font-weight:600">1,284</strong> followers</span>
            <span><strong style="color:var(--mv-fg);font-weight:600">312</strong> following</span>
          </div>
          <div style="display:flex;align-items:center;gap:.375rem;margin-top:.125rem;font-size:.75rem;color:var(--mv-fg-subtle)">
            <svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
            Joined March 2023
          </div>
        </div>
      </div>
    </div>
    <a class="mv-hover-card-trigger" href="#chloe" onclick="event.preventDefault()">@chloe</a></mv-hover-card>
  and its source code lives in
  <mv-hover-card placement="top" open-delay="300">
    <div data-content style="--mv-hover-card-width:19rem">
      <div style="display:grid;gap:.5rem;text-align:left">
        <div style="display:flex;align-items:center;gap:.5rem;color:var(--mv-fg)">
          <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="color:var(--mv-fg-muted)"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"/></svg>
          <strong style="font-weight:600">northwork/marvelous</strong>
          <span style="margin-left:auto;padding:0 .4rem;border:1px solid var(--mv-border);border-radius:999px;font-size:.6875rem;color:var(--mv-fg-muted)">Public</span>
        </div>
        <p style="margin:0;color:var(--mv-fg-muted);font-size:.8125rem;line-height:1.5">Native Web Components, layered CSS and zero dependencies.</p>
        <div style="display:flex;align-items:center;gap:1rem;font-size:.75rem;color:var(--mv-fg-subtle)">
          <span style="display:inline-flex;align-items:center;gap:.35rem"><span aria-hidden="true" style="width:.625rem;height:.625rem;border-radius:999px;background:var(--mv-warning)"></span>JavaScript</span>
          <span>★ 2.4k</span>
          <span>Updated 2 hours ago</span>
        </div>
      </div>
    </div>
    <a class="mv-hover-card-trigger" href="#repo" onclick="event.preventDefault()">northwork/marvelous</a></mv-hover-card>.
</div>

API

Attributes

NameTypeDefaultDescription
placementtop | bottom | left | right[-start|-end]bottomPreferred side, flipped when there isn’t enough room.
offsetnumber8Distance from the trigger (px).
open-delaynumber500Delay before opening (ms).
close-delaynumber300Grace delay before closing (ms).
arrowbooleanShows an arrow.
openbooleanOpens/closes programmatically.
disabledbooleanDisables the card.

Properties

NameTypeDescription
isOpenbooleanRead-only.

Events

NameDescription
mv-openAfter opening.
mv-closeAfter closing.

Content structure

NameDescription
first childTrigger, ideally a link (<a>) that makes sense on its own.
[data-content]Card content (uses the .mv-popover style).

CSS classes

NameDescription
mv-hover-card-triggerDotted-underline mention style for the trigger.

CSS variables

NameDefaultDescription
--mv-hover-card-width20remCard width.
--mv-popover-*Background, radius and padding inherited from Popover.

Accessibility

Visual enhancement: the trigger must make sense on its own. Opens on mouse hover and keyboard focus (:focus-visible), never on touch; Tab moves into the card (which stays open while focus is inside), Escape closes it. The content isn’t announced automatically: don’t put essential information in it.

Cette page a été traduite par IA. Signaler un problème de traduction