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).
Heading
Description
Heading
Description
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
- Deck region: wraps the whole grid and holds layout settings.
- Grid: arranges cards in columns according to your layout choice and breakpoints.
- 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 | |
|---|---|
| !Figma | CU Design System (Figma) (locate Card and layout patterns in the file). |
| !AEM | Card deck in AEM (in-dialog Help links to the design-system card deck page). |
| !WCAG | Meaningful sequence (WCAG 2.2) |
| !CDS | Card (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-parsysgetscolumn-countandcolumn-gapat breakpoints;.c-card__containerusesinline-blockand bottom margin. In edit mode, cards get a fixed width for authoring. - Equal rows (
.c-card-deck__rows):.card-deck-parsysisdisplay: flex; flex-flow: row wrap(when not in edit mode)..c-cardis flex; desktop widths use percentages withmargin-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:
| Value | Category | Where used |
|---|---|---|
20px | layout | column-gap for masonry (desktop and tablet). |
10px | layout | column-gap for masonry on small phones; horizontal gaps between floated cards on mobile. |
15px / 5px | layout | Bottom margin on .c-card__container (masonry desktop vs phone). |
1.5% | layout | Gutters 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-2throughcols-5,stack-tablet-1throughstack-tablet-4,stack-mobile-1throughstack-mobile-3combine to set breakpoints (implemented incard-deck-columns.lessandcard-deck-rows.less).
Behaviours
- Edit mode: The inner
divcan include classedit-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 at576pxto767px; mobile atmax-width: 575px.
Layout and spacing
- Masonry:
column-gap20px (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 perstack-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
h2orh3consistent 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
| Test | Status |
|---|---|
| Tab order through cards (links, buttons) | Recommended |
| Screen reader: card titles and body content | Recommended |
| Masonry: DOM vs visual reading order | Review per page |
| Equal rows: alignment and zoom | Recommended |
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)
| Field | Type | Purpose |
|---|---|---|
| Layout type | Select (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 class | Text | Optional 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 includescard-deck-columns.lessandcard-deck-rows.less. - Sling resource type:
concordia/components/card-deck.
Implementation
| File | Purpose |
|---|---|
apps/concordia/components/card-deck/card-deck.jsp | Inner 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.xml | Adds root class c-card-deck on the component HTML tag. |
apps/concordia/components/card-deck/dialog.xml | Layout type, column counts, optional CSS class; helpPath to design-system help page. |
etc/designs/concordia/clientlibs/card/less/card-deck-columns.less | Masonry / column layout. |
etc/designs/concordia/clientlibs/card/less/card-deck-rows.less | Equal rows / flex and float layouts. |
etc/designs/concordia/clientlibs/card/css.txt | Imports 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 field | Property | Maps to |
|---|---|---|
| Layout type | ./type | columns → c-card-deck__columns; rows → c-card-deck__rows. |
| Columns (desktop) | ./numColumnsDesktop | Class segment cols-{2..5}. |
| Columns (tablet) | ./numColumnsTablet | Class segment stack-tablet-{1..4}. |
| Columns (mobile) | ./numColumnsMobile | Class segment stack-mobile-{1..3}. |
| CSS class | ./additionalClass | Extra 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 fromcard.lessand both card-deck LESS files). - Parsys resource type
concordia/components/parsysforcard-deck-parsys. - Child Card components depend on the Card implementation and its clientlibs.
