Skip to content
kitn AI/UI

Card

kai-card

A presentational card surface. One element: structural slots for media, header, and footer, with appearance and orientation variants. Compose the content; the card owns the chrome.

  • Shadow DOM
  • 5 structural slots
  • appearance + orientation
  • 6 styleable parts
  • dismissible / clickable

The body is the default slot. The rest are structural regions, each rendered only when filled:

  • slot="media" — full-bleed image, video, or illustration. Pinned to the top (vertical) or start (horizontal), clipped to the card corners.
  • slot="header" — header content, e.g. a title. slot="header-actions" — an actions cluster at the end of the header row.
  • default slot — the body.
  • slot="footer" — footer content. slot="footer-actions" — buttons at the end of the footer row.
<kai-card appearance="filled" dismissible>
<img slot="media" src="/preview.png" alt="Report preview" />
<h3 slot="header">Quarterly report</h3>
Your Q2 numbers are ready to review.
<button slot="footer-actions">Open</button>
</kai-card>

Full-bleed media at the top, body below.

slot="header-actions" and slot="footer-actions" pin clusters to the end of each row.

footer-actions is responsive on its own: a right-aligned row when there is room, and a full-width vertical stack when the card is too narrow (a container query on the card’s width). Author the primary action last so it sits at the row’s right and rises to the top of the stack. kai-button fills the width automatically when stacked, so the same markup works at any width.

outlined (default), filled, plain, accent.

orientation="horizontal" puts the media at the start, content beside it.

orientation="responsive" is horizontal when the card’s container is wide enough and vertical when it is not. It is a container query on the card’s own width, so a card collapses wherever it is narrow (a sidebar, a grid cell), independent of the viewport. The footer action cluster collapses the same way on its own.

The breakpoint is the collapse prop (a CSS length, default 28rem); set collapse="32rem" to change it. Container-query breakpoints can’t be CSS variables, so this is a prop the card bakes into a per-instance @container rule, not a ::part token.

appearance="filled" + dismissible, with an illustration, title, description, and CTA in the body. The × fires kai-dismiss.

clickable makes the whole card a button (kai-card-click, Enter/Space). Do not combine it with action buttons.

dense tightens --kai-card-spacing for lists and feeds.

SlotModePurpose
injectThe card body, below the header/media regions.
injectFull-bleed media (image/video/illustration) at the top (vertical) or start (horizontal). Clipped to the card corners.
injectHeader content, e.g. a title. Rendered above the body.
injectAn actions cluster pinned to the end of the header row.
injectFooter content rendered below the body.
injectAction buttons pinned to the end of the footer. Do NOT combine with a clickable/href card (nested interactive).
PropertyTypeDefaultNotes
theme'auto'Color mode (`auto` follows prefers-color-scheme).
appearance'outlined'Surface treatment: `outlined` (default) | `filled` | `plain` | `accent`. Attribute: `appearance`.
orientation'vertical'`vertical` (default, media on top) | `horizontal` (media at the start) | `responsive` (horizontal when the card's container is wide enough, else vertical, via a container query on the card's own width). Attribute: `orientation`.
collapse'28rem'The card width below which a `responsive` card collapses to vertical and the footer actions stack. A CSS length; default `28rem`. Attribute: `collapse`.
densefalseTighter spacing for dense lists. Attribute: `dense`.
dismissiblefalseShow a close (×) that hides the card and emits `kai-dismiss`. Attribute: `dismissible`. Off by default.
hrefRender the whole card as a link. Attribute: `href`. Wins over `clickable`.
target`target` for the `href` anchor. Attribute: `target`.
rel`rel` for the `href` anchor. Attribute: `rel`.
clickablefalseMake the whole card a button (`role="button"`, Enter/Space, hover affordance) that emits `kai-card-click`. Attribute: `clickable`. Ignored when `href` is set.

This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.

Card