Card
Overview
ds-card groups related content, with optional media, a pinned tag, a close button, and a footer. Apply it to a <div> for a content container or an <a href="..."> when the whole card navigates to another page.
Cards are CSS components, not web components. Application code provides any dismiss or action behavior.
Options
Basic usage
Visual states
Cards support the global --alert, --warning, --success, --info, and --muted visual states.
Component colors
Cards support the full set of component color classes. Apply --color-* to the card to set its background and contrasting content color. With outline style, the selected color supplies the foreground instead.
Gradients
Apply a gradient class to the card for a named feature gradient or a color gradient. Named gradients supply a foreground color; color gradients use the default text color unless another color is set. Use --ds-card-text-color for a custom text color.
Direction suffixes such as -to-right, -to-left, -to-top, and -to-bottom work with both named and color gradients. Without a suffix, the direction is 165deg.
Icons
Use a child ds-icon for visible card content. An --icon-* class on the card itself selects the icon for its loading or message overlay. Both support the global icon set.
Horizontal layout
Add --horizontal to place an icon beside the content. Put one ds-icon before a ds-rows wrapper containing the heading and text. The icon stretches to the content height, while its size modifier controls the width of the icon panel.
Use --square on the icon for a tinted background and divider. The tint follows the icon color, including an explicit --color-* modifier. Without --square, the icon has no background panel.
An optional footer spans both columns. Horizontal cards inside ds-cols --uniform share card heights, but do not align their internal content rows with subgrid.
Size
The manifest lists --small and --large. --small reduces the card’s indent and gap; --large increases its corner radius. These modifiers do not resize child text or set the card’s width or height.
Width
Control card width through its layout container, such as ds-cols. For a responsive grid with a minimum column width, see Uniform style.
Height
Cards grow with their content. The panel variant adds a minimum height of 140px; it does not impose a fixed height.
Alignment
Use --center to center grid items and text horizontally and --middle to center the content vertically. Use --centered for both axes, or combine --center --middle.
Children inherit the card’s text alignment, so --center also centers text inside full-width children. A child’s own alignment modifier, such as ds-text --right, takes precedence. --middle does not change horizontal or text alignment.
Vertical alignment needs spare height, supplied here by --ds-card-height. Cards with an in-flow footer stretch their rows to keep the footer at the bottom, even with --middle or --centered.
Indent
Cards support global indent modifiers such as --indent-large, --indent-small, --indent-xsmall, and --no-indent. Standard cards use two grid gutter tracks for the horizontal inset, with children placed between content-start and content-end. Vertical inset uses padding.
Gap
Cards support global gap modifiers. The grid row gap controls the spacing between direct children, including adjacent images and footers. First and last children receive no extra spacing.
Axis modifiers can override the base gap independently. A standard card has one column, so changing its horizontal gap alone does not create visible space.
For horizontal cards, card gap modifiers control the gutter between the icon panel and the content, the gap above the footer, and spacing inside the ds-rows content wrapper. The card retains its standard outer padding. Set an axis modifier on the wrapper itself when it needs to override the card’s gap.
Loading state
--loading hides the card contents and displays a centered spinning icon while retaining the content’s layout space; a pinned tag remains visible in this state. --loading-refresh uses the alternative refresh icon.
Add data-ds-message to display text with the loading icon, as shown in Message state.
Message state
data-ds-message hides the card contents and displays an icon with the attribute’s text. Combine it with --loading for an animated loading message, or --icon-* for a custom icon. Remove the attribute to restore the content when loading has also finished.
Styles
Variants
Default style
The default card has a background, rounded corners, and a shadow. An image or figure can appear before the text and extend to the card’s edges.
Details style
--details applies additional styling:
Panel style
--panel sets a minimum height of 140px and strengthens the shadow on hover. It does not set a minimum width.
Plain style
--plain removes the shadow and adds a tinted background on hover.
Simple style
--simple removes the shadow, adds a 2px border, and uses a tinted background on hover.
Outline style
--outline uses a transparent background, a 2px border, and no shadow. Like --simple, it adds a tinted background on hover.
With --outline, --color-* supplies the foreground and its paired contrast color supplies the base --ds-card-background-color. Transparency and hover tints affect only the painted background, so button labels and tag text do not become transparent. A child’s own --color-* modifier takes precedence over the card’s color mapping. Choose a foreground color that contrasts with the surface behind the transparent card.
Tiled style
--tiled removes the grid row gap and turns every child into a full-width tile that uses the row gap as its vertical inset, so highlighted rows and dividers run edge to edge while the content keeps its rhythm. Images, dividers and positioned controls keep their own geometry. It can be combined with --panel, and with --no-indent for edge-to-edge media.
For a fuller example, see Tiled billing panel.
Clickable style
An <a class="ds-card" href="..."> automatically gets a pointer cursor and a link indicator on hover. --clickable applies the same visual treatment to other card elements, but does not add navigation, a click handler, or keyboard behavior. Prefer a native anchor for navigation.
CSS custom properties
Set these properties on the card itself using CSS, a style attribute, or JavaScript. The defaults below apply to an unmodified card; modifiers can change them.
| Property | Default | Description |
|---|---|---|
--ds-card-width |
auto |
Card width |
--ds-card-height |
auto |
Card height |
--ds-card-text-color |
var(--color-contrast, var(--color-default)) |
Text color, also supplied to child content |
--ds-card-background-color |
var(--color, var(--color-gray-bright)) |
Base background and contrasting child-content color; outline and hover styles adjust the painted surface separately |
--ds-card-border-color |
var(--color-transparent) |
Border color |
--ds-card-border-width |
0px |
Border width |
--ds-card-border-style |
solid |
Border style |
--ds-card-border-radius |
12px |
Corner radius, also used by edge media, footers, and datatables |
--ds-card-indent |
var(--space-medium) |
Base content inset, adjusted by --indent-* modifiers |
--ds-card-v-indent |
var(--ds-card-indent) |
Vertical content inset, adjusted by --v-indent-* modifiers |
--ds-card-h-indent |
var(--ds-card-indent) |
Horizontal content inset, adjusted by --h-indent-* modifiers |
--ds-card-gap |
var(--space-xsmall) |
Content spacing, adjusted by --gap-* modifiers |
Properties prefixed with --_card- are private implementation details, not supported overrides.
Composition
Nested cards start their own color palette, including when placed inside a content wrapper. Apply --color-* or the public card color properties to the nested card when it needs a particular palette. For a transparent nested card, choose a text color that contrasts with the surface behind it.
Child components
Use direct-child components such as ds-heading, ds-text, ds-list, ds-cols, and ds-rows so they can receive the card’s inset spacing.
Media
A direct child i.ds-icon, img, or figure can provide the card’s media. Media remains inside the content track, including when placed first. Footers and dividers use the same content width. The --outdent class does not change card child placement.
Pinned tag
Place ds-tag --pinned first so the following content receives the extra top inset.
Footer
Place a footer or .__footer last. Use a native footer or div.__footer for content, or button.__footer for an action. Do not nest a button or another link inside an anchor card.
Card with close button
Place button.__close first, before the content, and keep the footer last. SDS positions the button at the top-right corner; application code must implement dismissal.
Used inside other components
Use ds-cols for columns and ds-rows for stacked cards. Connected and uniform layouts are applied to the parent ds-cols, not to each card.
The card manifest lists --limit, but the current stylesheet does not implement it on a standalone ds-card. Use layout-container width controls instead. For card content alignment, see Alignment.
Connected style
When cards are placed inside a ds-cols --connected element, they will have visual connectors applied between elements. Keep the cards in one row so each connector points to the preceding card; this example scrolls horizontally on narrow screens.
The connectors are styled according to the following rules:
Uniform style
ds-cols --uniform creates a responsive grid with a default minimum column width of 320px. Cards expand to fill the available space and wrap to new rows. Corresponding children share row heights through CSS subgrid.
Set --ds-cols-width on the parent ds-cols, not on the cards. This example uses min(300px, 100%) for a 300px minimum that fits smaller containers. Alternatively, --width-narrow sets a fixed 280px minimum.
The container and cards have separate gap controls: --gap-large on ds-cols spaces the cards, while --gap-small on each card spaces its content. Cards also support the individual axis modifiers described in Gap.
Keep the same number and order of content children in every card. Keep an empty element when a corresponding content slot has no content.
Accessibility
Role and ARIA attributes
A content card does not need an interactive role. Use meaningful headings within it, meaningful alternative text for informative images, and aria-hidden="true" for decorative icons.
Loading and message overlays are visual CSS states, not live regions. Set aria-busy="true" while updating a card and provide a separate status announcement when needed. Do not rely on CSS-generated message text as the only accessible status.
Keyboard access
Use native links for navigation and buttons for actions. Give every control an accessible name, including icon-only close buttons. After dismissing a card, application code should move focus to a logical remaining control.
Javascript
There is no card-specific JavaScript to initialize. Application code adds and removes loading classes and data-ds-message, handles close and footer actions, and manages focus and accessible status updates.
Examples
Image and footer
Size comparison
Billing panel
Tiled billing panel
Tiled usage panel
Tiled media card
Manifest
The component manifest describes this component's API: its modifiers, structure, data attributes, CSS custom properties, accessibility notes, and example markup. It is consumed by tooling such as AI assistants and code generators.
Latest version: https://assets.soracom.io/sds/3.42.2/ds-card/manifest.json?v=3.42.2