コンテンツにスキップ

ホバーカード

hc-hovercard は hc-tooltip の、より 豊かなコンテンツを持つ兄弟です。ポップアップにアバター、タイトルと サブタイトル、段落の説明、インタラクティブなリンクが必要なとき — 短いテキストラベルでは足りないあらゆる場面で使います。よくある例: GitHub 風の @user メンションプレビュー、issue ID のプレビュー、 ページリンクのプレビュー。

hc-tooltip や hc-menu と同じプリミティブの上に構築されています: ネイティブの popover 属性、CSS Anchor Positioning、開閉の ルーティングのための installHovercard()。ツールチップとの 挙動上の主な違い:

  • カードはポインタイベントを受け取ります(pointer-events: none なし)。ユーザーはカーソルをカードへ移動して中のリンクをクリック できます。
  • ビヘイビアはトリガーとカードの両方でホバー状態を追跡します — どちらかがホバーされている間、カードは開いたままです。
  • 表示 / 非表示の遅延は長め(500 ms / 200 ms)で、読み物カードの UX に合わせています。

別名: プレビューカード。

プリミティブ 必要バージョン
HTML popover Chrome 114、Edge 114、Firefox 125、Safari 17
CSS Anchor Positioning Chrome 125、Edge 125、Firefox 147、Safari 26

アンカー未対応のブラウザは、デフォルトの下配置 + flip-block の CSS パスを鏡写しにした getBoundingClientRect 配置へフォールバック します。

Hover or focus Ada Lovelace for a richer preview.

AL
Ada Lovelace
Mathematician

First computer programmer. View profile →

import { installHovercard } from '@hypermedia-components/core';
installHovercard();

installHovercard() は冪等で、アンインストーラを返します。ゼロ設定の @hypermedia-components/core/behaviors エントリが自動インストールし、 htmx でスワップされた内容も自動で拾います。

installHovercard() の表示 / 非表示ルーティング

Section titled “installHovercard() の表示 / 非表示ルーティング”
トリガーイベント 効果
トリガーの mouseenter 500 ms 後の表示を予約。
トリガーの mouseleave 200 ms 後の非表示を予約(保留中の表示をキャンセル)。
トリガーの focus 即座に表示(a11y)。
トリガーの blur 200 ms 後の非表示を予約。
カードの mouseenter 保留中の非表示をキャンセル。
カードの mouseleave 200 ms 後の非表示を予約。
トリガーまたはカードでの Escape 閉じる。

トリガーまたはカードのどちらかがホバーされている間、カードは 開いたままなので、カーソルは両者の間の小さな隙間を、解散させずに 通過できます。

カードはデフォルトでトリガーの下に開きます。data-side (top / right / bottom / left)と、任意の data-align (start / center / end、デフォルト center)で上書きします。 ポインタには data-arrow を足します。

<a href="/users/grace" aria-describedby="grace-card">Grace Hopper</a>
<div class="hc-hovercard" id="grace-card" data-side="right" data-arrow>…</div>

これは方向つき配置の機構をツールチップとポップオーバーと共有します — CSS Anchor Positioning + JS フォールバック。共有の機構は 基礎 → アンカー配置を、 Baseline の注記は ポップオーバー → 方向つき配置を 参照してください。

カード本文は、トリガー自身のホバー / フォーカスから遅延取得します: htmx の from: 修飾子でリンク側をリッスンし、スワップ先はカードに します。

<a href="/users/ada" id="ada-link"
aria-describedby="ada-card">Ada Lovelace</a>
<div class="hc-hovercard" id="ada-card"
data-hx-get="/users/ada/preview"
data-hx-trigger="mouseenter once from:#ada-link, focus once from:#ada-link"
data-hx-target="this">
<span class="hc-spinner" aria-hidden="true"></span>
</div>

once により最初のホバー(またはキーボードフォーカス)でフラグメントを 取得し、サーバーはカードの内側 HTML を返します。同じ遅延読み込み契約の 全体はレイジーパネルのレシピが 文書化しています。

  • トリガーは aria-describedby でカードを参照するため、視覚的に 描画されているかにかかわらず、トリガーのフォーカス時にスクリーン リーダーがカードのテキストを読み上げます。
  • ホバーカードのコンテンツは補足です。ページの理解に必要なものは 文書本文にも置かなければなりません。
  • 主要なアクションをホバーカードの中に置かないでください — ホバー しないユーザーには決して見えません。「プロフィール全体を見る」への リンクは問題ありませんが、それが引き起こすアクションはトリガー要素 から直接も到達可能であるべきです(例: トリガー自体が同じリンク)。
  • Escape は常に、フォーカスを動かさずにカードを閉じます。

component トークン(component.tokens.json):

トークンパス 用途
hovercard.bg / fg / border / radius 面。
hovercard.max-width 折り返しまでの上限。
hovercard.padding / gap 内側のレイアウト。
hovercard.offset アンカー時のトリガーからの距離。
hovercard.title-weight .hc-hovercard__title のフォントウェイト。
hovercard.subtitle-fg / subtitle-size .hc-hovercard__subtitle の色とサイズ。
生成される CSS 変数を表示
--hc-hovercard-bg | -fg | -border | -radius
--hc-hovercard-max-width | -padding | -gap | -offset
--hc-hovercard-title-weight
--hc-hovercard-subtitle-fg | -subtitle-size