Theme
Version
GitHub PyPI Discord
On this page

HoverCard

Use CHoverCard to preview supplementary profile, document, or destination details on hover and keyboard focus. Essential information and actions must remain available without the preview.

HoverCard at a glance

HoverCard at a glance
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class HoverCardAtAGlance(Component):
    template = """
      <p>Meet
        <c-CHoverCard>
          <c-fill name="activator" data="{ activator_attrs }">
            <a href="#maya" c-bind="activator_attrs">Maya Chen</a>
          </c-fill>
          <c-fill name="default">
            <c-CStack gap="sm">
              <c-CAvatar>MC</c-CAvatar>
              <strong>Maya Chen</strong>
              <span>Field researcher ยท 18 shared observations</span>
            </c-CStack>
          </c-fill>
        </c-CHoverCard>
      </p>
    """


preview = HoverCardAtAGlance()
preview  # noqa: B018

Preview a document

Preview a document
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class DocumentHoverCard(Component):
    template = """
      <c-CHoverCard placement="top-start">
        <c-fill name="activator" data="{ activator_attrs }">
          <a href="#survey" c-bind="activator_attrs">Northern reef survey</a>
        </c-fill>
        <c-fill name="default">
          <c-CStack gap="sm">
            <strong>Northern reef survey</strong>
            <span>Updated today ยท 42 observations</span>
            <c-CProgress c-value="68" label="Review progress" />
          </c-CStack>
        </c-fill>
      </c-CHoverCard>
    """


preview = DocumentHoverCard()
preview  # noqa: B018

Control visibility

Control HoverCard
Show code
# ruff: noqa: E501

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class ControlledHoverCard(Component):
    template = """
      <div x-data>
        <c-CHoverCard $c-props="{open:$store.hoverExample.open,onOpenChange:(next)=>$store.hoverExample.open=next}">
          <c-fill name="activator" data="{ activator_attrs }">
            <a href="#atlas" c-bind="activator_attrs">Atlas workspace</a>
          </c-fill>
          <c-fill name="default"><strong>Atlas</strong><p>12 collaborators ยท Active now</p></c-fill>
        </c-CHoverCard>
        <c-CButton variant="outline" @click="$store.hoverExample.open=!$store.hoverExample.open">Toggle preview</c-CButton>
      </div>
    """
    js = "Alpine.store('hoverExample',{open:false});"


preview = ControlledHoverCard()
preview  # noqa: B018

Tune delays

Tune HoverCard delays
Show code
# ruff: noqa: E501

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class HoverCardDelays(Component):
    template = """
      <c-CGroup>
        <c-CHoverCard c-delay="0" c-close_delay="0">
          <c-fill name="activator" data="{ activator_attrs }"><a href="#instant" c-bind="activator_attrs">Instant</a></c-fill>
          <c-fill name="default">No opening or closing delay.</c-fill>
        </c-CHoverCard>
        <c-CHoverCard c-delay="900" c-close_delay="500">
          <c-fill name="activator" data="{ activator_attrs }"><a href="#deliberate" c-bind="activator_attrs">Deliberate</a></c-fill>
          <c-fill name="default">A slower, forgiving preview.</c-fill>
        </c-CHoverCard>
      </c-CGroup>
    """


preview = HoverCardDelays()
preview  # noqa: B018

Choose placement

Place HoverCard
Show code
# ruff: noqa: E501

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class HoverCardPlacements(Component):
    template = """
      <c-CGroup style="padding-block:8rem">
        <c-CHoverCard placement="top-start">
          <c-fill name="activator" data="{ activator_attrs }"><a href="#top" c-bind="activator_attrs">Top start</a></c-fill>
          <c-fill name="default">Collision-aware top preview.</c-fill>
        </c-CHoverCard>
        <c-CHoverCard placement="bottom-end">
          <c-fill name="activator" data="{ activator_attrs }"><a href="#bottom" c-bind="activator_attrs">Bottom end</a></c-fill>
          <c-fill name="default">Collision-aware bottom preview.</c-fill>
        </c-CHoverCard>
      </c-CGroup>
    """


preview = HoverCardPlacements()
preview  # noqa: B018

Choose size and arrow

HoverCard sizes
Show code
# ruff: noqa: E501

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class HoverCardSizes(Component):
    template = """
      <c-CGroup>
        <c-CHoverCard size="sm">
          <c-fill name="activator" data="{ activator_attrs }"><a href="#small" c-bind="activator_attrs">Small</a></c-fill>
          <c-fill name="default">A compact preview card.</c-fill>
        </c-CHoverCard>
        <c-CHoverCard size="lg" c-arrow="False">
          <c-fill name="activator" data="{ activator_attrs }"><a href="#large" c-bind="activator_attrs">Large without arrow</a></c-fill>
          <c-fill name="default">A generous preview without a pointer arrow.</c-fill>
        </c-CHoverCard>
      </c-CGroup>
    """


preview = HoverCardSizes()
preview  # noqa: B018

Nested color schemes

HoverCard themes
Show code
# ruff: noqa: E501

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class HoverCardThemes(Component):
    template = """
      <c-CGroup>
        <div style="color-scheme:light;background:Canvas;color:CanvasText;padding:2rem">
          <c-CHoverCard>
            <c-fill name="activator" data="{ activator_attrs }"><a href="#day" c-bind="activator_attrs">Day profile</a></c-fill>
            <c-fill name="default"><strong>Light scheme</strong><p>Follows its anchor context.</p></c-fill>
          </c-CHoverCard>
        </div>
        <div style="color-scheme:dark;background:Canvas;color:CanvasText;padding:2rem">
          <c-CHoverCard>
            <c-fill name="activator" data="{ activator_attrs }"><a href="#night" c-bind="activator_attrs">Night profile</a></c-fill>
            <c-fill name="default"><strong>Dark scheme</strong><p>Follows its anchor context.</p></c-fill>
          </c-CHoverCard>
        </div>
      </c-CGroup>
    """


preview = HoverCardThemes()
preview  # noqa: B018

Customize HoverCard

Customize HoverCard
Show code
# ruff: noqa: E501

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CustomizedHoverCard(Component):
    template = """
      <c-CHoverCard
        style="--cui-hover-card-background:#fff8eb;--cui-hover-card-foreground:#7a2e0e;
               --cui-hover-card-border-color:#f79009;--cui-hover-card-radius:1.25rem"
      >
        <c-fill name="activator" data="{ activator_attrs }"><a href="#coral" c-bind="activator_attrs">Coral study</a></c-fill>
        <c-fill name="default"><strong>Coral study</strong><p>Warm brand adaptation.</p></c-fill>
      </c-CHoverCard>
    """


preview = CustomizedHoverCard()
preview  # noqa: B018

Accessibility and interaction

The activator keeps its authored accessible name, navigation, and click behavior. The preview is aria-hidden supplementary content and cannot contain focusable or interactive descendants. Focus opens it visually; Escape and blur close it without moving focus. Touch contact does not open it.

Use CTooltip for a concise accessible description and CPopover when people must interact with the overlay.

API reference

Inputs

CHoverCard server inputs

Server inputs are passed in a template through <c-CHoverCard ... /> or in Python through CHoverCard(...).

InputTypeDefaultEffect
idstr | NonegeneratedSets private surface identity and exposes it as slot data.
openboolFalseSets the server-visible initial state and uncontrolled fallback.
disabledboolFalseSuppresses visual opening without changing the activator itself.
delayint600Sets the first fine-pointer hover delay in milliseconds from 0 through 60000. Focus remains immediate.
close_delayint300Sets the pointer bridge delay in milliseconds from 0 through 60000.
placement"top-start" | "top" | "top-end" | "bottom-start" | "bottom" | "bottom-end" (CHoverCardPlacement)"bottom-start"Sets the preferred logical placement. Collision fallback may choose another rendered side.
arrowboolTrueShows the owned decorative pointer arrow.
size"sm" | "md" | "lg" (CHoverCardSize)"md"Selects preview width padding and text scale.
class_str | Mapping[str, bool] | Sequence[CClassValue] | None (CClassValue)NoneAdds surface classes and merges them with attrs.
stylestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] | None (CStyleValue)NoneAdds surface inline styles and merges them with attrs; Citry retains anchor ownership.
attrsMapping[str, object] | NoneNoneAdds allowed native, Alpine, and data attributes to the HoverCard surface. Owned presence, semantics, focus, and relationships are rejected.

CHoverCard client inputs

Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CHoverCard />.

InputTypeOmitted behaviorEffect
openboolean | nullReleases control and preserves the current committed state. null has the same effect.Controls visual visibility while supplied as a Boolean. Disabled still dominates.
disabledbooleanUses the server input.Controls HoverCard-local availability.
delayintegerUses the server input.Controls future first-hover delay from 0 through 60000 milliseconds.
closeDelayintegerUses the server input.Controls the pointer bridge from 0 through 60000 milliseconds.
placement"top-start" | "top" | "top-end" | "bottom-start" | "bottom" | "bottom-end" (CHoverCardPlacement)Uses the server input.Controls requested placement and data-placement.
arrowbooleanUses the server input.Reactively shows or hides the decorative arrow.
sizeCHoverCardSizeUses the server input.Reactively changes card geometry.
onOpenChangefunctionDoes not notify a component callback.Receives hover, focus, dismissal, peer, press, and external-native visibility requests.

Slots

Slots are passed as nested content or <c-fill> tags in a template, or through the slots={...} argument in Python.

CHoverCard slots

SlotRequiredDataFallback
activatoryes{activator_attrs: dict[str, object], hover_card_id: str} (CHoverCardActivatorSlotData)none
defaultyes{} (CHoverCardDefaultSlotData)none

Events

Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.

CHoverCard events

EventSignatureTrigger and timingDetailControlled and cancellation behavior
onOpenChange(requestedOpen: boolean, detail: CHoverCardOpenChangeDetail) => void (CHoverCardOpenChangeDetail)Hover, focus, pointer departure, blur, Escape, trigger press, a peer HoverCard, or external native visibility requests another state.{reason: "hover" | "focus" | "pointer-leave" | "blur" | "escape" | "press" | "peer" | "native" | "ancestor" | "modal", controlled: boolean, forced: boolean, source: EventTarget | null} (CHoverCardOpenChangeDetail)Uncontrolled requests commit before notification. Controlled requests wait for the owner. Owner commits do not notify.

Methods

-

CSS

CSS variables to theme the components. Set them on an ancestor or the component itself.

CHoverCard CSS variables

Apply these variables to CHoverCard or one of its ancestors.

VariableTypePurposeDefault
--cui-hover-card-backgroundcolorSurface background.Canvas
--cui-hover-card-foregroundcolorSurface text.CanvasText
--cui-hover-card-border-colorcolorSurface boundary.Subtle currentColor mix.
--cui-hover-card-radiuslengthSurface corner radius.0.75rem
--cui-hover-card-shadowshadowTop-layer elevation.Scheme-aware layered shadow.
--cui-hover-card-inline-sizelengthPreferred preview width.Size-derived.
--cui-hover-card-max-inline-sizelengthMaximum preview width.22rem
--cui-hover-card-paddinglengthContent padding.Size-derived.
--cui-hover-card-offsetlengthGap between activator and surface.0.375rem
--cui-hover-card-durationtimeEntry and exit duration; reduced motion resolves to zero.100ms
--cui-hover-card-easingeasingEntry and exit easing.cubic-bezier(0.2, 0.8, 0.2, 1)

Attributes

HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.

CHoverCard attributes

AttributeElementTypeMeaning
popoverSurface"manual"Uses native top-layer presence while Citry owns timing and dismissal.
aria-hiddenSurface"true"Keeps supplementary visual content outside the accessibility tree.
data-openSurfacepresent | absentMirrors logical visual visibility; absent during exit.
data-placementSurfacesix placement strings (CHoverCardPlacement)Mirrors requested placement, not the collision fallback result.
data-sideSurface"top" | "bottom"Mirrors the collision-settled physical block side.
data-sizeSurfaceCHoverCardSizeReflects preview geometry.
data-arrowSurfacepresent | absentReflects decorative arrow visibility.

Selectors

Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.

CHoverCard selectors

SelectorElementPurpose
[data-citry-ui-part="host"]Host divActivator and surface ownership boundary.
[data-citry-ui-part="hover-card"]SurfaceVisual surface and attrs destination.
[data-citry-ui-part="content"]Content divSupplementary flow content wrapper.
[data-citry-ui-part="arrow"]Decorative spanCollision-side pointer mark.

Interfaces

Aliases and data shapes referenced above.

Input type aliases

InterfaceDefinition
CClassValuestr | Mapping[str, bool] | Sequence[CClassValue]
CStyleValuestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue]
CHoverCardPlacementLiteral["top-start", "top", "top-end", "bottom-start", "bottom", "bottom-end"]
CHoverCardSizeLiteral["sm", "md", "lg"]

CHoverCardActivatorSlotData

FieldTypeDefaultMeaning
activator_attrsdict[str, object]-Owned trigger marker and CSS anchor style.
hover_card_idstr-Generated or authored surface identity.

CHoverCardDefaultSlotData

Empty dataclass: {}.

CHoverCardOpenChangeDetail

FieldTypeDefaultMeaning
reason"hover" | "focus" | "pointer-leave" | "blur" | "escape" | "press" | "peer" | "native" | "ancestor" | "modal"-Source of the requested visibility change.
controlledboolean-Whether a valid client open Boolean currently owns state.
forcedboolean-Whether structural or modal safety required the component to close regardless of controlled ownership.
sourceEventTarget | null-Browser source associated with the request.

Translation keys

-