Card
- New
Default
Use this when the card contains one destination and no other links.
- The whole card is clickable.
- Hit area is stretched from the single heading link.
- Underline is what marks the card as clickable.
Show code
<div class="iai-card-group">
<div class="iai-card">
<div class="iai-card__heading">
<h3 class="govuk-heading-m">
<a class="iai-card__link" href="#">Dashboard</a>
</h3>
</div>
<div class="iai-card__content">See the state of everything in one place.</div>
</div>
<div class="iai-card">
<div class="iai-card__heading">
<h3 class="govuk-heading-m">
<a class="iai-card__link" href="#">Reports</a>
</h3>
</div>
<div class="iai-card__content">Generate and download service reports.</div>
</div>
<div class="iai-card">
<div class="iai-card__heading">
<h3 class="govuk-heading-m">
<a class="iai-card__link" href="#">Settings</a>
</h3>
</div>
<div class="iai-card__content">Manage your account and preferences.</div>
</div>
</div>---
import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-astro";
---
<CardGroup>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-react";
export default function Example() {
return (
<CardGroup>
<Card>
<CardHeading>
<h3 className="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 className="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 className="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>
);
}<script>
import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-svelte";
</script>
<CardGroup>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-solid";
export default function Example() {
return (
<CardGroup>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>
);
}Clickable link card
Coming soon
Secondary Variant
Use the secondary variant on a light-grey surface where the card set sits within existing content and does not need a bordered, standalone frame.
Show code
<div class="iai-card-group">
<div class="iai-card iai-card--secondary">
<div class="iai-card__heading">
<h3 class="govuk-heading-m">
<a class="iai-card__link" href="#">Dashboard</a>
</h3>
</div>
<div class="iai-card__content">See the state of everything in one place.</div>
</div>
<div class="iai-card iai-card--secondary">
<div class="iai-card__heading">
<h3 class="govuk-heading-m">
<a class="iai-card__link" href="#">Reports</a>
</h3>
</div>
<div class="iai-card__content">Generate and download service reports.</div>
</div>
<div class="iai-card iai-card--secondary">
<div class="iai-card__heading">
<h3 class="govuk-heading-m">
<a class="iai-card__link" href="#">Settings</a>
</h3>
</div>
<div class="iai-card__content">Manage your account and preferences.</div>
</div>
</div>---
import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-astro";
---
<CardGroup>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-react";
export default function Example() {
return (
<CardGroup>
<Card secondary>
<CardHeading>
<h3 className="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 className="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 className="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>
);
}<script>
import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-svelte";
</script>
<CardGroup>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>import { CardGroup, Card, CardHeading, CardLink, CardContent } from "@i-dot-ai-npm/component-library-solid";
export default function Example() {
return (
<CardGroup>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Dashboard</CardLink>
</h3>
</CardHeading>
<CardContent>See the state of everything in one place.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Reports</CardLink>
</h3>
</CardHeading>
<CardContent>Generate and download service reports.</CardContent>
</Card>
<Card secondary>
<CardHeading>
<h3 class="govuk-heading-m">
<CardLink href="#">Settings</CardLink>
</h3>
</CardHeading>
<CardContent>Manage your account and preferences.</CardContent>
</Card>
</CardGroup>
);
}When to use
Use a card to group related content and actions into a bounded region, so people can scan a set of options and act on the one they want.
We have evidence of the card working in three contexts:
- Dashboards — where a user needs to see the state of several things at once and move into one of them.
- Home screens — where the card set is the primary navigation into a product's main areas.
- Landing pages presenting parallel destinations — where the options are of equal standing and the user picks one.
The common factor is a set of options at the same level, where the user chooses between them rather than reading through them in order.
When not to use
Do not use a card to highlight content inside long-form content
If the page is prose and you want to draw attention to part of it, the card is the wrong container. It creates a destination-shaped region in content that has no destinations.
Use instead:
- Inset text — to emphasise a short passage in place.
- Details — to hide supplementary content behind a disclosure.
- Warning text — where the content is a consequence the user must not miss.
- A panel — for a confirmation or end-of-journey outcome.
Do not use a card to compensate for weak information hierarchy or content design
This was the first concern the 2018 GDS review panel recorded, and it is the most common failure mode.
If a page is hard to scan, a card set will not fix it — it will divide the same unstructured content into boxes. Cards make an existing hierarchy visible. They do not create one.
Before reaching for a card, check that the content has been cut, that headings describe what is under them, and that the page has a clear purpose. If those things are not true, fix them first. If they are true, you may not need cards at all.
Do not use a card where a summary list, task list or table is the honest structure
- Use a summary list where the content is a set of name/value pairs about one thing — a check-your-answers page, a record of what a user has entered.
- Use a task list where the items are steps in a process with a status each, and the user works through them.
- Use a table where the items share the same fields and the user needs to compare across them. Cards break comparison, because the eye has to travel from box to box instead of down a column.
A card set that repeats the same three fields in every card is a table drawn badly.
Do not use a card with an image unless there is evidence the image helps users
An image adds weight, load time and an alternative-text obligation. Include one only if you can say what job it does for the user.
If the image is decorative, remove it. If it distinguishes cards in a set, consider the icon slot above, which is smaller, decorative, and does not need alternative text. If the image carries information the user needs, that information probably belongs in the card text.
Tokens
View token values
Measured values are contrast ratios against the surface the token sits on.
| Token | Value | Measured |
|---|---|---|
--card-surface | #ffffff | — |
--card-surface-secondary | #f3f2f1 light-grey | text 17.52 · link 4.62 · 1.12 vs page |
--card-surface-hover | #0b0c0c ink | 19.59 on white |
--card-text-hover | #ffffff | 19.59 on ink · focus 14.55 |
--card-border | #b1b4b6 $govuk-border-colour | 2.08 — decorative framing |
--card-border-width | 2px | — |