# Card Cards group related content or controls into a distinct, bounded section. Section: components Docs: https://nebula.kaluza.com/components/card --- ## When to use - To visually separate a self-contained piece of content from the surrounding page - To group related fields, details, or controls that belong to the same subject - As the structural container for more complex components such as AccordionGroup or banners - When you need a clearly bounded section within a page that does not warrant a full page region ## When not to use - **For tabular data** - use [Data Table](/components/data-table) instead, which provides sorting, alignment, and header semantics that a Card cannot. - **For key-value pairs** - use [Summary List](/components/summary-list) instead, which is designed for displaying labelled data. - **As a clickable navigation element** - card has no interactive semantics. If the whole card should be clickable, use a [CTA Link](/components/cta-link) or [CTA Button](/components/cta-button) as the primary action, and keep the card itself non-interactive. - **For brief status information attached to an object** - use [Badge](/components/badge) instead. ## Anatomy 1. **Container** (the bordered, rounded surface that holds the card's content) 2. **Content area** (the padded inner region; accepts any child components) ## Basic usage ```tsx Plastic Recycling

Nearly all types of plastics can be recycled. However, the extent to which they are recycled depends upon technical, economic and logistic factors.

``` ## Variants and features ### Other HTML elements By default, Card renders as a `div`. Use the `as` prop (from styled-components) to render as a different semantic element when the content warrants it. - Use `as="section"` when the card represents a landmark region with a heading - Use `as="article"` when the card's content is independently distributable - Use `as="fieldset"` when the card groups related form fields (pair with a `legend`) A card as a landmark region, with its heading naming the region: ```tsx Your usage

You used 212 kWh of electricity last month.

``` A card as a fieldset, grouping related form fields. The `legend` must be the first element inside it: ```tsx Supply address ``` The `inline` prop is deprecated and must not be used. ## Composition Card is a general-purpose container. There are no restrictions on what it can contain, but some patterns work better than others. Keep each card focused on a single subject. A card that covers too many topics forces users to read everything to find what they need. If you find yourself splitting a card with internal headings into many sub-sections, consider whether the content should be broken into multiple cards or moved to its own page. Limit the number of actions in a card. A single primary action is appropriate. If you need more, use one primary and one secondary action at most. ## Rules and guidance ### Usage - **Card** SHOULD group content that relates to a single subject or task. Rationale: A card that spans multiple unrelated subjects forces users to read everything rather than scanning. Multiple focused cards are easier to navigate. [id: card.single-subject; testability: manual] - **Card** MUST NOT be used to present tabular data in place of a Data Table. Rationale: Data Table provides sorting, alignment, and semantic table structure that a Card cannot replicate. [id: card.no-table-replacement; testability: context] - **Card inline prop** MUST NOT be used. Rationale: The inline prop is deprecated and has no effect on the component's behaviour. [id: card.inline-deprecated; testability: auto] ### Interaction - **Card** MUST NOT be made entirely clickable as a navigation element. Rationale: Card has no interactive semantics. Making the whole surface clickable is inaccessible and ambiguous to keyboard and screen reader users. [id: card.not-interactive; testability: manual] ### Composition - If rendered as a fieldset: **Card** MUST include a legend element as the first child. Rationale: A fieldset without a legend is invalid HTML and provides no group label to assistive technology. [id: card.fieldset-legend; testability: auto] - **Card** SHOULD use the as prop to render the appropriate semantic HTML element for its content. Rationale: The default div has no semantic meaning. Where the card represents a section with a heading, an article, or a group of form fields, a more specific element improves accessibility. [id: card.semantic-element; testability: manual] - If rendered as a section or article element: **Card** SHOULD include a heading that describes its content. Rationale: Landmark elements without a heading cannot be distinguished from one another by screen reader users navigating by region. [id: card.section-heading; testability: manual] - **Card** SHOULD NOT contain more than one primary action. Rationale: Multiple primary actions compete for attention and make it unclear what the most important next step is. [id: card.primary-action-limit; testability: manual] - **Card** SHOULD NOT contain so much content that it requires internal sub-headings to organise. Rationale: If a card needs its own heading hierarchy, the content likely belongs on its own page or split across multiple cards. [id: card.no-overloaded-content; testability: manual] ## Accessibility ### In brief Card is a styled `div` with no role and no name. A screen reader announces what is inside it and nothing else, so the structure comes from the content you put in. ### What Nebula provides - A bordered, padded container that never takes focus and adds nothing to the accessibility tree. - The `as` prop changes the element it renders, for example to a `fieldset`. ### Accessible design #### Start each card with a heading that names it A card is only a visual boundary, so a screen reader user cannot find or skip one except through its heading. Open every card with a heading that says what it holds. WCAG: [1.3.1 Info and Relationships](https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html) [2.4.6 Headings and Labels](https://www.w3.org/WAI/WCAG22/Understanding/headings-and-labels.html) ### Accessible development #### Choose the heading level for the card's place in the outline The card does not set a level. A card on the page takes the level below the page title, and a card nested inside another takes the next level down. WCAG: [1.3.1 Info and Relationships](https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html) #### If a card groups form controls, render it as a fieldset with a legend A `fieldset` and its `legend` name the group for a screen reader user. Pass `as="fieldset"` to the card and render its heading as a `legend`. WCAG: [1.3.1 Info and Relationships](https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html) [3.3.2 Labels or Instructions](https://www.w3.org/WAI/WCAG22/Understanding/labels-or-instructions.html) ### Accessibility testing status Reviewed on 9 October 2026 against v17.0.1. | Test | Status | Tested with | | --- | --- | --- | | Default state | Tested | axe-core via the Storybook test runner (CI) | | Advanced states | Partially tested | axe-core via the Storybook test runner (CI) | | Keyboard navigation | Manually tested | keyboard (reported by the owner) | | Screen reader | Partially tested | VoiceOver with Chrome (reported by the owner) | What each test covers: - Default state: The component as it first appears, before anything is clicked or changed. - Advanced states: Every other state and variant: error, open, selected, each size and style, and hovering. - Keyboard navigation: Whether every function can be reached and used with the keyboard alone, with a visible focus ring. - Screen reader: Whether a screen reader announces what is on screen correctly: the name, the role and any state. What these statuses mean: - Tested: Every check in this row passed in an automated run that repeats on every pull request. - Manually tested: Every check in this row was run once, by a person or with a tool they started, and all of them passed. It is not re-run on every change. - Partially tested: Some checks in this row were run once and passed; the rest are still to do. - Issue found: A check in this row failed. The ticket is shown beside the status. - Not tested: No check in this row has been run yet. - Not applicable: This row does not apply to the component, for the reason given beside it. The table records which checks were run on this component on its own. It is not a statement of WCAG conformance, and it does not cover how the component is used. ## Properties ### Card Also accepts all props from `HTMLAttributes`. - `inline` (type `boolean`, optional). Has no effect. - `as` (type `ElementType`, optional). Renders the component as a different element or component, e.g. `as="section"`. - `forwardedAs` (type `ElementType`, optional). Like `as`, but passed on to the component being wrapped, for when a styled wrapper should keep its own element and change the one beneath it. ## Styles Reference only; you do not need this to use the component. This is the CSS its styled elements use, with theme tokens shown by name. `${...}` is an interpolation (a theme token, a mixin or another value from the code). A `&[prop]` or `@when ` block holds CSS that applies only under that condition; these are notation, not valid CSS. ### card ```css background: ${colors.canvas}; border-radius: ${radii.standard}; border: ${borderWidths.standard} solid ${colors.borderMuted}; box-shadow: 'none'; padding: ${space[3]}; ${mediaQueries.smallAndUp} { padding: ${space.cardPadding}; } ```