Skip to main content

Card

<zeno-card>LayoutSource

A bordered surface for one subject, with optional cover, header and footer.

import '@usezeno/tokens/css';
import '@usezeno/core/web-components';

Examples​

Basic​

title and subtitle make the header. Everything inside the element is the body.

The report has 24 pages and three attachments.
<zeno-card title="Annual report" subtitle="Updated on 9 March">
The report has 24 pages and three attachments.
</zeno-card>

Elevation and outline​

elevation goes from 0 to 4 and sets the shadow. outlined replaces the shadow with a border.

Elevation 0 Elevation 1 Elevation 2 Elevation 3 Elevation 4 Outlined
<zeno-card elevation="0">Elevation 0</zeno-card>
<zeno-card elevation="1">Elevation 1</zeno-card>
<zeno-card elevation="2">Elevation 2</zeno-card>
<zeno-card elevation="3">Elevation 3</zeno-card>
<zeno-card elevation="4">Elevation 4</zeno-card>
<zeno-card outlined>Outlined</zeno-card>

Clickable and selected​

A clickable card can take focus and fires a click on Enter or Space. The card does not change selected itself, so the page does it.

Billed every month. Billed once a year.
<zeno-card clickable outlined title="Monthly plan">Billed every month.</zeno-card>
<zeno-card clickable outlined selected title="Yearly plan">Billed once a year.</zeno-card>
const cards = document.querySelectorAll('zeno-card');
cards.forEach(card => {
card.addEventListener('click', () => {
cards.forEach(other => {
other.selected = other === card;
});
});
});

Compact, loading and disabled​

compact uses less padding. loading covers the card with a spinner. disabled dims it and stops clicks.

Less space around the content. The content is on its way. This card cannot be used.
<zeno-card compact outlined title="Compact">Less space around the content.</zeno-card>
<zeno-card loading outlined title="Loading">The content is on its way.</zeno-card>
<zeno-card disabled clickable outlined title="Disabled">This card cannot be used.</zeno-card>

Attributes and properties​

PropertyAttributeTypeDefaultDescription
elevationelevationreflects0 | 1 | 2 | 3 | 41
outlinedoutlinedreflectsbooleanfalse
interactiveinteractivereflectsbooleanfalse
clickableclickablereflectsbooleanfalse
selectedselectedreflectsbooleanfalse
loadingloadingreflectsbooleanfalse
disableddisabledreflectsbooleanfalse
compactcompactreflectsbooleanfalse
noHeaderBorderno-header-borderreflectsbooleanfalse
noFooterBorderno-footer-borderreflectsbooleanfalse
titletitlestring''
subtitlesubtitlestring
hrefhrefstring
targettargetstring
relrelstring
testIdstringTest ID for automated testing From ZenoElement.

Methods​

MethodDescription
focus(): voidFocus the component or its first focusable element From ZenoElement.
blur(): voidBlur the component or its focused element From ZenoElement.

Events​

This element sends no events.

Slots​

SlotDescription
DefaultThe body.
coverAn image or other media above the header.
footerActions or secondary content.
headerReplaces the title and subtitle.

CSS parts​

Part
base
body
cover
footer
header
loading
subtitle
title

CSS custom properties​

This element documents no custom properties of its own. Style it through its parts and through the tokens it reads.

The element's own source reads no tokens.

Accessibility​

Keyboard​

KeyWhat it does
TabMoves focus to the card, when it is clickable or has an href.
EnterSpaceFires a click on a card that is clickable, unless it is disabled or loading. Keys pressed in a control inside the card are left to that control.

Forms​

This element is not a form control. It adds nothing to a form's data.

Notes​

  • The card renders an <article>. Its name is the aria-label you set, or the title.
  • With clickable or href the role changes to button and the card joins the tab order.
  • A clickable card has aria-pressed, which follows selected.
  • disabled sets aria-disabled="true".
  • The title text is rendered as an <h3>.

Tests and known gaps​

  • No tests of its own. The only check is that the element registers and renders (smoke.test.ts).
  • Not checked with axe-core.
  • Has no Storybook story.
23 of the 30 properties, methods, events, slots and parts above have no description in the source
  • the property elevation
  • the property outlined
  • the property interactive
  • the property clickable
  • the property selected
  • the property loading
  • the property disabled
  • the property compact
  • the property noHeaderBorder
  • the property noFooterBorder
  • the property title
  • the property subtitle
  • the property href
  • the property target
  • the property rel
  • the part base
  • the part body
  • the part cover
  • the part footer
  • the part header
  • the part loading
  • the part subtitle
  • the part title

Known gaps:

  • The cover, header and footer slots do not work. Each slot is rendered only when the card already knows it has content, and the card can only learn that from the slot itself. Content given to these slots never shows.
  • href alone does nothing. The card becomes a button in the tab order, but a click or Enter does not open the address unless clickable or interactive is also set.
  • A card with href is announced as a button, not a link. It opens the address from script, so “open in new tab”, the status bar address and the link context menu are missing.
  • interactive alone is for the mouse only. The card looks clickable but stays out of the tab order.
  • A card that is not clickable still has tabindex="-1", so a mouse click moves focus to it.
  • Every clickable card is announced as a toggle button, pressed or not pressed, also when it only opens something.
  • A disabled clickable card stays in the tab order.
  • loading does not set aria-busy. The content under the overlay can still be read and reached with the keyboard.
  • The title is always an <h3>. The level cannot be changed to fit the page outline.
  • The header text uses the title attribute, which is also the native tooltip. Hovering the card shows the same text again as a tooltip.