Cards
A bordered container — usually an <article> — with no padding of its own. Padding comes from .card-section, so images can bleed to the edge.
A card has no background of its own — it's a border on whatever surface it's sitting on. For a panel that reads as lifted off the canvas, add a surface class: .card.bg-soft for a neutral lift, or .bg-primary / any family to theme it. The surface brings its own text, heading and muted / subtle colours with it, so everything inside stays readable.
Title
Here the image is inside .card-section, so it's inset with the text and gets flow spacing below it.
Parts
- .card-section — a padded block. Stack several; the top padding collapses between adjacent ones.
- .card-image — on an <img> (or a wrapper). Full-width; inside a section it also gets bottom spacing.
- .card-footer — a section pinned to the bottom of the card. Handy in an equal-height row for a call-to-action.
Equal height
In a .grid, cards in a row are the same height automatically, and .card-footer pins to the bottom.
Short
A little text.
Tall
Much more text, so this card is taller. The other two stretch to match, and their footers still line up along the bottom edge.
Short
A little text.
The flex .row engine needs .equal-height added explicitly for the same result. .row children should only ever be .col — wrap the card rather than putting .col on the .card itself:
Short
A little text.
Tall
Much more text, so this card is taller. The other two stretch to match, and their footers still line up along the bottom edge.
Short
A little text.
Overriding
Set the --jf-card-* custom properties (tabled below) on .card, your own card modifier, or a scoped selector — padding is per axis (--jf-card-padding-x and --jf-card-padding-y), both taking $card-padding at build — not on :root, where the component's own declaration would shadow them. Or the Sass variables below, before import.
Variables
Sass variables
| Name | Default | Notes |
|---|---|---|
| $card-padding | token(space-md) | Build-time default for both --jf-card-padding-x and --jf-card-padding-y. |
| $card-border-radius | token(radius-lg) | Corner radius → --jf-card-border-radius. The card is overflow: hidden, so a .card-image is clipped to it. |
| $card-border-width | token(border-width) | Border width → --jf-card-border-width. |
| $card-border-style | solid | Border style → --jf-card-border-style. |
Custom properties
| Name | Default | Notes |
|---|---|---|
| --jf-card-padding-x | $card-padding | Inline padding on .card-section — flatten the sides without touching top and bottom. |
| --jf-card-padding-y | $card-padding | Block padding on .card-section. Adjacent sections still collapse their shared edge to zero. |
| --jf-card-border-color | falls back to --jf-border-color | Not emitted by default — set it to give cards a border colour of their own without moving the shared one. |