Clickable Card
Card as one fully clickable element — dashboard tile, list card, navigation tile. Card automatically renders as <a> or <button> depending on the prop; nested <a><Card></Card></a> is unnecessary (and usually wrong).
Live Preview
Dashboard tile with navigation (href)
List card with action (onclick)
Navigation tile with icon (href + icon)
Features
- href automatically sets the rendered element to <a> with correct tab order
- onclick sets it to <button type="button"> for actions without navigation
- Hover/focus styles kick in automatically once href/onclick/clickable is set — no "decorative hover" mode on passive elements
- mint="lift" or mint="glow" for a gentle micro-interaction
- Anti-pattern comparison: why <a><Card></Card></a> is the worse solution
Code
Stat tile with href (renders as <a>)
List card with onclick (renders as <button>)
Delegate click without onclick (clickable prop)
Anti-pattern: wrapping Card in <a>
Don't
<a href="/revenue">
<Card variant="outlined" padding="md">
Content
</Card>
</a> - Card keeps
elementType="div"— no hover/focus styles - Inner inputs/links produce nested interactive elements (a11y violation)
- Two tab stops (outer a + card content) instead of one
- Screen readers announce "link, region, …" twice
Do
<Card
variant="outlined"
padding="md"
href="/revenue"
>
Content
</Card> - Card renders directly as
<a> - Hover/focus styles apply automatically
- One tab stop, one element for screen readers
- No conflicts with inner buttons (stop bubbling where needed)
Best Practices
href for navigation, onclick for actions
Routes, detail pages → href. Opening a modal,
changing a selection, server actions → onclick.
That way Cmd-click "open in new tab" works as expected.
Inner buttons: stopPropagation
If the card contains a secondary button (e.g. "Favorite"), end the button's onclick with event.stopPropagation() — otherwise the card fires too.
mint="lift" for a gentle hover animation
mint="lift" lifts the card slightly on hover; mint="glow" adds a subtle glow. prefers-reduced-motion is respected.
clickable for delegated click handlers
When click behavior is handled by a wrapper component and the card should render as a
real button without carrying an onclick itself — set clickable without href/onclick. The card then
renders as <button type="button"> with interactive
styles. Don't combine it with an outer <a> or inner buttons — <a><Card clickable> produces nested interactive elements.
No "decorative hover"
Card deliberately has no mode with hover styles but no click source. A pointer cursor
plus a lift animation on a passive element violates WCAG 3.2 Predictable. If the card
sits inside an outer <a>, move the href onto the card (see the anti-pattern section).