Layout grid + cards

Arrange content in columns of cards — use spatial structure to express "these items are peers; you can compare them horizontally." Useful for feature comparisons, option lists, three-way trade-offs, team / case showcases.


When to use

  • N peer options for the reader to compare side by side (product tiers / pricing / tools)
  • Multiple parallel features as a card grid (homepage features section)
  • Triangle of arguments — objective comparison of plan A / B / C
  • Team / case studies — one card per person or case
  • ❌ Single block of information — use Callout
  • ❌ Wildly uneven content lengths — cards become misaligned, visually broken
  • ❌ Strict sequence (step 1 → 2 → 3) — use Stepper

Basic syntax

```layout grid cols=3
:::card accent=blue
**Plan A**

Short description + one or two key points.
:::

:::card accent=red
**Plan B**

Short description + one or two key points.
:::

:::card accent=green
**Plan C**

Short description + one or two key points.
:::
```

Renders: 3 equal-width cards side by side; each has a colored accent bar on top; on narrow screens, they stack into a single column automatically.


All options

Block-level: ```layout grid

Option Type Default Purpose
cols int (1-6) 2 Number of columns. Below 720px, auto-collapses to 1 column

Card-level: :::card

Option Type Default Purpose
accent enum gray Color of the top accent bar (6 choices)

Accent palette (6 colors):

Value Visual Recommended use
blue Blue Neutral / informational / featured
red Red Warning / high-risk / not recommended
green Green Recommended / passing / success
yellow Yellow Attention / requires care
purple Purple Premium / Pro / special
gray Gray Neutral / default (omitting accent gives this)

Examples

Example 1: 3-column product tiers

```layout grid cols=3
:::card accent=gray
**Free**

- Personal use
- 5 documents
- Community support

$0/month
:::

:::card accent=blue
**Pro**

- Personal pro
- Unlimited documents
- Email support
- Private sharing

$10/month
:::

:::card accent=purple
**Team**

- Team collaboration
- SSO + audit
- Priority support
- 99.9% SLA

$50/month
:::
```

Renders: three equal-width cards with gray / blue / purple accent bars. The Pro tier carries the strongest visual weight (blue), Team is marked "premium" (purple). Readers see the hierarchy at a glance.

Example 2: nested callout

```layout grid cols=2
:::card accent=green
**Recommended: A**

> [!INFO]
> Plan A fits 90% of users; zero-config out of the box.

Detailed explanation...
:::

:::card accent=red
**Not recommended: B**

> [!WARN]
> Plan B requires self-hosting. Advanced users only.

Detailed explanation...
:::
```

Renders: two cards, each holding a callout (INFO / WARN). The card provides layout, the callout provides semantic emphasis — distinct responsibilities.

Example 3: single column (cols=1)

```layout grid cols=1
:::card accent=blue
A full-width card — like "a paragraph with an accent bar."
:::
```

Renders: a single full-width card. Looks like a callout, but the semantics differ — this is "a grouped content block," not "a highlighted note."

Example 4: 4 columns or more

```layout grid cols=4
:::card accent=blue
Feature 1
:::
:::card accent=blue
Feature 2
:::
:::card accent=blue
Feature 3
:::
:::card accent=blue
Feature 4
:::
```

Renders: 4 equal columns. On a desktop screen, each card is ~250px wide. Above 4 columns, content gets cramped — 5/6 columns work only for icon + one-line text.


Plain-text fallback behavior

:::card is a markdown directive container (CommonMark Container Blocks proposal). In readers without directive support:

:::card accent=blue
**Plan A**
Description
:::

:::card accent=blue and ::: show as plain text; the markdown content inside the cards still renders (bold, lists, links, etc., all work).

Per-reader breakdown:

Reader Render
Rho Full grid + cards + accent
GitHub web :::card accent=blue literal + card content as standard markdown
Obsidian Some plugins support it (obsidian-callout, containers); default shows literal
VS Code default preview ::: literal + content as standard markdown
cat / less Source as plain text

Content remains readable in every case — only the layout visual disappears.


Common pitfalls

1. Wrong accent value

:::card accent=skyblue   ← ❌ Not recognized; falls back to gray
:::card accent=BLUE      ← ⚠️ Case-sensitive; lowercase recommended
:::card accent=blue      ← ✅

Only six valid values: blue / red / green / yellow / purple / gray.

2. Forgot to close :::

```layout grid cols=2
:::card accent=blue
Content A
                ← ❌ Missing :::
:::card accent=red
Content B
:::
```

→ The whole layout block fails to parse. Every :::card needs a paired ::: to close.

3. cols mismatches the number of cards

```layout grid cols=3
:::card accent=blue
A
:::
:::card accent=red
B
:::
```

→ Two cards in a 3-column layout — the third column is empty. Doesn't error, but the visual is asymmetric. Either change to cols=2 or add a third card.

4. Severely uneven card content

```layout grid cols=2
:::card accent=blue
Plan A: very long description, 5 paragraphs, 3 lists, nested callout, code block...
:::
:::card accent=red
Plan B: one sentence.
:::
```

→ The left card is tall, the right card looks chopped. Visually broken. Fix: bring the right card up to comparable length, or use Stepper (one at a time) or Tabs.

5. Don't nest layout in layout

```layout grid cols=2
:::card
```layout grid cols=2     ← ❌ Don't nest
:::card
:::
:::card
:::
```
:::
```

→ The inner grid behavior is undefined. Layouts shouldn't nest. If you need complex structure, switch to Stepper or rethink the page.

6. Putting interact blocks inside cards — fine, but watch hydration

:::card accent=blue
```interact
slider x range=0..10 step=1 default=5
template stl:
[selected] -> [{x}]
```
:::

✅ Fully supported (see Nested DSL). But the card's height changes as the interact block renders — sliding may shift adjacent cards. Suggestion: give the interact block a fixed min-height, or place it on its own row outside the grid.


See also

  • Callout — Single-passage emphasis; different semantic slot from layout
  • Tabs — Same space, switchable content (saves vertical space)
  • Stepper — Strict sequential walkthrough (one step at a time)
  • Nested DSL — Embedding callout / interact / etc. inside layout cards
  • Plain-text fallback principle
Open in Rho MD →