Card deck

Use a card deck when you need multiple cards in a responsive grid with masonry or equal-height rows.

A card deck lays out several Card components in a responsive grid so people can scan and compare related items (for example programs, stories, or people) on one screen. The deck controls layout and columns; each card still carries its own image, title, body, and optional action.

You can choose between two layout approaches: masonry, where cards keep natural heights and fill columns top to bottom, and equal rows, where cards in a row share height for a cleaner edge (equal rows are only meant for certain full-width page templates; see the component help and Code for constraints).

Behaviour

Column counts can differ for desktop, tablet, and phone so the grid stays readable as the viewport narrows. Fewer columns on small screens keeps tap targets and line length manageable.

Masonry suits mixed content lengths. Equal rows suits when you want a uniform row height in supported templates. If you need equal-height alignment but your page is not in a supported full-width template, prefer masonry or adjust the page structure.

The deck is a container only: authors add Card components inside it. The deck does not supply card copy or imagery by itself.

Anatomy

Card deck anatomy

  1. Deck region: wraps the whole grid and holds layout settings.
  2. Grid: arranges cards in columns according to your layout choice and breakpoints.
  3. Cards: each item is a Card (or another allowed child) placed inside the deck.

Content guidelines

  • Add one card per item and keep titles and imagery consistent across the set so the grid feels like one module.
  • Set layout (masonry vs equal rows) and column counts in the component settings before fine-tuning individual cards.
  • Avoid very long lists of cards where people would be better served by filters, pagination, or another pattern; the deck works best for bounded sets people can overview at a glance.
  • Use the optional extra CSS class field only for approved layout hooks; avoid one-off styling that breaks the design system.

When to use

  • A related set of items that each fit the Card pattern (image, title, short text, optional link or button).
  • When you want a responsive grid without custom layout work.
  • When equal-height rows improve scan lines in a supported full-width context.

When not to use

  • A single card; place a Card directly on the page or in a simpler container.
  • Content that is not card-shaped; use a layout that matches those components.
  • Very long galleries where people need search, sort, or pagination first.
  • Equal rows when the page template does not support it; use masonry or change the template (see Code).

Best practices

Do

  • Prefer equal rows when you need aligned card heights in supported templates; prefer masonry when heights vary a lot or templates are constrained.
  • Keep column counts modest on small screens and avoid cramming four or five columns on desktop when cards feel tight.
  • Order cards in the authoring order that matches the story you want in a linear reading path.

Don't

  • Assume masonry visual order (down each column) matches a simple left-to-right read; screen readers follow the document order. Check order if the sequence must tell a specific story (see Accessibility).
  • Nest a deck only to wrap one card unless a parent pattern requires that wrapper.

Related

Resource
!FigmaCU Design System (Figma) (locate Card and layout patterns in the file).
!AEMCard deck in AEM (in-dialog Help links to the design-system card deck page).
!WCAGMeaningful sequence (WCAG 2.2)
!CDSCard (Concordia Design System)

Card deck layout is styled under #boot .c-card-deck. Masonry uses column-count on .card-deck-parsys; equal rows use flexbox on the parsys and percentage widths on .c-card. Card appearance (colours, type) comes from the Card styles in card.less, not from the deck LESS files alone.

Anatomy (visual)

  • Masonry (.c-card-deck__columns): .card-deck-parsys gets column-count and column-gap at breakpoints; .c-card__container uses inline-block and bottom margin. In edit mode, cards get a fixed width for authoring.
  • Equal rows (.c-card-deck__rows): .card-deck-parsys is display: flex; flex-flow: row wrap (when not in edit mode). .c-card is flex; desktop widths use percentages with margin-right: 1.5% and nth-child clearing. Tablet and phone use float-based columns with horizontal padding between cells.

Design tokens

The deck LESS files rely mainly on layout values (gaps, widths, media queries). They do not reference CDS custom properties directly; spacing examples:

ValueCategoryWhere used
20pxlayoutcolumn-gap for masonry (desktop and tablet).
10pxlayoutcolumn-gap for masonry on small phones; horizontal gaps between floated cards on mobile.
15px / 5pxlayoutBottom margin on .c-card__container (masonry desktop vs phone).
1.5%layoutGutters between cards in equal rows (desktop).

Card-level tokens (for example font and colour on each card) are defined in the Card component and card.less.

Variants (style)

  • Layout type: Masonry vs equal rows (see Usage).
  • Column classes: cols-2 through cols-5, stack-tablet-1 through stack-tablet-4, stack-mobile-1 through stack-mobile-3 combine to set breakpoints (implemented in card-deck-columns.less and card-deck-rows.less).

Behaviours

  • Edit mode: The inner div can include class edit-mode; masonry and row rules often skip layout transforms so authors can edit without broken column flow.
  • Responsive: Desktop rules apply at min-width: 768px; tablet at 576px to 767px; mobile at max-width: 575px.

Layout and spacing

  • Masonry: column-gap 20px (10px on narrow mobile); card containers have bottom margin between items.
  • Equal rows: desktop card widths vary by cols-; tablet and mobile adjust width and padding per stack-tablet- / stack-mobile-*.

The Card deck is a layout wrapper. It does not define a single interactive role; accessibility depends on the Card content (headings, links, images, alt text). Two layout modes behave differently for reading order:

  • Equal rows: DOM order is typically a reasonable match for visual row order.
  • Masonry: CSS columns can make the visual reading order (down each column) differ from a simple top-to-bottom DOM order in the parsys. Review order of items in the parsys and test with a screen reader if the sequence must match a specific narrative.

Semantics

  • Use a logical heading structure inside each card (for example card title as h2 or h3 consistent with the page outline).
  • If the deck represents a list of parallel items, the parent page heading structure should introduce the section; individual cards should not skip heading levels.

Keyboard

  • Focus moves through focusable elements inside each card (links, buttons) in DOM order.
  • The deck itself is not a tab stop; there is no special keyboard pattern for the container.

Screen reader

  • The container is not announced as a landmark by default; cards are announced as their own content.
  • For Masonry, verify that the experience still makes sense when linearised in DOM order.

Focus and visibility

  • Focus styles follow the Card and link styles inside each card.
  • No Card deck-specific animation is defined in the deck LESS.

Testing

TestStatus
Tab order through cards (links, buttons)Recommended
Screen reader: card titles and body contentRecommended
Masonry: DOM vs visual reading orderReview per page
Equal rows: alignment and zoomRecommended

WCAG / guidelines

  • Understanding meaningful sequence (WCAG 2.2): ensure the order of content makes sense when linearised.
  • Card-level criteria (contrast, target size, alt text) apply to each Card; see Card component documentation and the design system.

CRXDE Lite query

Use this query in CRXDE Lite to find instances of this component.

/jcr:root/content//*[@sling:resourceType = 'concordia/components/card-deck']

Card deck pattern in the codebase

The Card deck pattern (c-card-deck, c-card-deck__columns, c-card-deck__rows, card-deck-parsys) appears in more than one place:

Context Location Authorable? Notes
Card deck apps/concordia/components/card-deck/ Yes Main authorable component; inner layout div + card-deck-parsys for Cards.
News list (landing) news-events/news-list/landing-scripts/ (listitem_top_news.jsp, listitem_more_news.jsp) No Fixed markup with c-card-deck__columns, cols-2, and related classes for news cards.
Individual profile list individual-profile-list/individual-profile-list.html No (HTL) Uses c-card-deck__rows and dynamic cols-${model.numColumns}.
Program list program-list/program-list.jsp No Uses c-card-deck__rows, cols-4, and a card-deck-parsys with a fixed id for program cards.

Where the deck is not authorable, layout and classes are driven by the parent component or template. Use the Card deck component when authors need to add and arrange cards freely on a page.

Authoring fields (summary)

FieldTypePurpose
Layout typeSelect (Masonry, Equal rows)Masonry: cards flow top to bottom in each column with natural heights. Equal rows: cards flow left to right in rows with equal heights (only in full-width templates per dialog help).
Columns (desktop)Select (2 to 5)Default: 3. Number of columns from 768px and up (masonry column count or row widths).
Columns (tablet)Select (1 to 4)Default: 1. Layout between 576px and 767px.
Columns (mobile)Select (1 to 3)Default: 1. Layout up to 575px.
CSS classTextOptional additionalClass on the inner layout div.

Component entry points

  • Authorable component: concordia/components/card-deck. Renders a layout wrapper and a parsys for child components. Styles ship with the card clientlib (apps.concordia.card), which includes card-deck-columns.less and card-deck-rows.less.
  • Sling resource type: concordia/components/card-deck.

Implementation

FilePurpose
apps/concordia/components/card-deck/card-deck.jspInner layout div: edit-mode, c-card-deck__rows or c-card-deck__columns, cols-, stack-tablet-, stack-mobile-*, additionalClass; includes card-deck-parsys.
apps/concordia/components/card-deck/_cq_htmlTag/.content.xmlAdds root class c-card-deck on the component HTML tag.
apps/concordia/components/card-deck/dialog.xmlLayout type, column counts, optional CSS class; helpPath to design-system help page.
etc/designs/concordia/clientlibs/card/less/card-deck-columns.lessMasonry / column layout.
etc/designs/concordia/clientlibs/card/less/card-deck-rows.lessEqual rows / flex and float layouts.
etc/designs/concordia/clientlibs/card/css.txtImports card.less, card-deck-columns.less, card-deck-rows.less.

Anatomy (markup)

  • Root: HTML tag carries class="c-card-deck" (from _cq_htmlTag).
  • Inner: <div class="[edit-mode] c-card-deck__columns|c-card-deck__rows cols-{n} stack-tablet-{n} stack-mobile-{n} [additionalClass]"> then <cq:include path="card-deck-parsys" resourceType="concordia/components/parsys" />.
  • Child components render inside the parsys (typically concordia/components/card).

Authoring (dialog)

Dialog fieldPropertyMaps to
Layout type./typecolumns → c-card-deck__columns; rows → c-card-deck__rows.
Columns (desktop)./numColumnsDesktopClass segment cols-{2..5}.
Columns (tablet)./numColumnsTabletClass segment stack-tablet-{1..4}.
Columns (mobile)./numColumnsMobileClass segment stack-mobile-{1..3}.
CSS class./additionalClassExtra classes on the inner layout div.

Variants / options

  • Template constraint for equal rows: Follow the in-dialog description when choosing Equal rows (full-width templates).
  • Program list and other templates: May duplicate class names (c-card-deck__rows, cols-4, etc.) with server-driven markup; behaviour matches the same LESS.

Dependencies

  • Clientlib category apps.concordia.card (CSS from card.less and both card-deck LESS files).
  • Parsys resource type concordia/components/parsys for card-deck-parsys.
  • Child Card components depend on the Card implementation and its clientlibs.