Agriculture Design System
Beta
Design System for the Export Service

Card

Cards are layout components used to link to more information or for secondary in-page navigation.

View in FigmaView in StorybookView in Github
import { ... } from '@ag.ds-next/react/card';

This is the legacy (versions v1.26.0 and below) documentation for Cards.

To support more card use-cases, v1.27.0 changed the <Card> API to also allow specific footer and header props. These props place their content in defined areas of the card to provide better control of their styling.

Card headers

Use <CardHeader> to give the card heading more visual prominence.

<CardHeader> must come before <CardInner>.

Open in Playroom, opens in a new tab
<Columns as="ul" cols={2}>
	<Card as="li">
		<CardHeader>
			<Heading as="h3" type="h4">
				Static card header
			</Heading>
		</CardHeader>
		<CardInner>
			<Text as="p">Descriptive content</Text>
		</CardInner>
	</Card>

	<Card as="li">
		<CardHeader background="bodyAlt">
			<Heading as="h3" type="h4">
				Static card header
			</Heading>
		</CardHeader>
		<CardInner>
			<Text as="p">Descriptive content</Text>
		</CardInner>
	</Card>

	<Card as="li" clickable shadow>
		<CardHeader>
			<Heading as="h3" type="h4">
				<CardLink href="#">Clickable card header</CardLink>
			</Heading>
		</CardHeader>
		<CardInner>
			<Text as="p">Descriptive content</Text>
		</CardInner>
	</Card>

	<Card as="li" clickable shadow>
		<CardHeader background="bodyAlt">
			<Heading as="h3" type="h4">
				<CardLink href="#">Clickable card header</CardLink>
			</Heading>
		</CardHeader>
		<CardInner>
			<Text as="p">Descriptive content</Text>
		</CardInner>
	</Card>
</Columns>

Card footers

Add supplementary information, links or actions to cards by passing a <CardFooter> after the <CardInner> container.

Outside footers

Use the footerOutside={true} prop to render the footer directly beneath the card.

In v1.26.0 and below, the footerOustide prop will degrade the visuals, UX and accessibility of various card configurations, especially when clickable or <CardHeader> is used. We recommend migrating to the footer and header props for all instances.

() => {
	const [isAdded, setIsAdded] = React.useState(false);
	return (
		<Columns as="ul" cols={2}>
			<Card>
				<CardInner>
					<Stack gap={1}>
						<H3>Card title</H3>
						<Text as="p">Descriptive content</Text>
					</Stack>
				</CardInner>
				<CardFooter>Supplementary info</CardFooter>
			</Card>

			<Card as="li" footerOutside>
				<CardInner>
					<Stack gap={1}>
						<H3>Card title</H3>
						<Text as="p">Descriptive content</Text>
					</Stack>
				</CardInner>
				<CardFooter>
					<ToggleButton
						iconType="star"
						label="Add to favourites"
						onClick={setIsAdded}
						pressed={isAdded}
						pressedLabel="Remove from favourites"
					/>
				</CardFooter>
			</Card>

			<Card as="li" clickable shadow>
				<CardInner>
					<Stack gap={1}>
						<H3>
							<CardLink href="#">Card title</CardLink>
						</H3>
						<Text as="p">Descriptive content</Text>
					</Stack>
				</CardInner>
				<CardFooter>Supplementary info</CardFooter>
			</Card>

			<Card as="li" clickable footerOutside shadow>
				<CardInner>
					<Stack gap={1}>
						<H3>
							<CardLink href="#">Card title</CardLink>
						</H3>
						<Text as="p">Descriptive content</Text>
					</Stack>
				</CardInner>
				<CardFooter>
					<ToggleButton
						iconType="star"
						label="Add to favourites"
						onClick={setIsAdded}
						pressed={isAdded}
						pressedLabel="Remove from favourites"
					/>
				</CardFooter>
			</Card>
		</Columns>
	);
};

Images

For a full-width image in a card, add the img tag outside the <CardInner> container. For images with inner padding (such as an icon), add it within the <CardInner> container.

<Columns as="ul" cols={2}>
	<Card as="li">
		<PlaceholderImage />
		<CardInner>
			<Stack gap={1}>
				<Text as="p">Descriptive content</Text>
				<CardLink href="#">Relevant link</CardLink>
			</Stack>
		</CardInner>
	</Card>

	<Card as="li">
		<CardInner>
			<Stack gap={1}>
				<PlaceholderPictogram />
				<Text as="p">Descriptive content</Text>
				<CardLink href="#">Relevant link</CardLink>
			</Stack>
		</CardInner>
	</Card>
</Columns>

Clickable cards

For cards that contain a single link, the hit area for that link can be made to wrap the entire card. This pattern may be used on cards that act as a preview for an article or blog post, for example. These cards could contain an image, a title and a brief summary of the article.

Fully-clickable cards must be given the clickable and shadow props to make itself and its <CardLink> appropriately indicate the clickable region. Do not wrap cards in an anchor tag as this can be a difficult experience for screen reader users.

<Columns as="ul" cols={2}>
	<Card as="li" clickable shadow>
		<PlaceholderImage />
		<CardInner>
			<Stack gap={1}>
				<H3>
					<CardLink href="#">Clickable card title</CardLink>
				</H3>
				<Text as="p">Descriptive content</Text>
			</Stack>
		</CardInner>
	</Card>

	<Card as="li" footerOutside clickable shadow>
		<PlaceholderImage />
		<CardInner>
			<Stack gap={1}>
				<H3>
					<CardLink href="#">Clickable card title</CardLink>
				</H3>
				<Text as="p">Descriptive content</Text>
			</Stack>
		</CardInner>
		<CardFooter>
			<TextLink href="#">Related action</TextLink>
		</CardFooter>
	</Card>
</Columns>

Equal card heights

The content within each card will often vary in height, so to prevent an uneven, ragged appearance of multiple cards within a list, ensure that the <Card> itself is the immediate child of a flex or grid component, such as <Columns>.

<Columns as="ul" cols={2}>
	<Card
		as="li"
		clickable
		footer={
			<CardFooter>
				<TextLink href="#">Related action</TextLink>
			</CardFooter>
		}
		footerOutside
		shadow
	>
		<CardInner>
			<Stack gap={1}>
				<H3>
					<CardLink href="#">Clickable card title 1</CardLink>
				</H3>
				<Text>
					Vestibulum non dui vitae augue efficitur viverra quis sit amet enim.
					Vestibulum sagittis lacus arcu, eu interdum elit lobortis a. Aliquam
					sit amet sollicitudin orci, sit amet rhoncus odio.
				</Text>
			</Stack>
		</CardInner>
	</Card>

	<Card as="li" clickable shadow>
		<CardInner>
			<Stack gap={1}>
				<H3>
					<CardLink href="#">Clickable card title 2</CardLink>
				</H3>
				<Text>
					Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut dictum
					magna justo, ac mattis dolor sollicitudin fringilla.
				</Text>
			</Stack>
		</CardInner>
	</Card>

	<Card
		as="li"
		footer={
			<CardFooter>
				<CardLink href="#">Related action</CardLink>
			</CardFooter>
		}
	>
		<CardHeader>
			<H3>
				<CardLink href="#">Card header 3</CardLink>
			</H3>
		</CardHeader>
		<CardInner>
			<Stack gap={1}>
				<Text>
					Sed volutpat non enim ac efficitur. Etiam ut dolor tempor, tempor
					tortor at, luctus elit.
				</Text>
			</Stack>
		</CardInner>
	</Card>

	<Card>
		<CardInner>
			<Stack gap={1}>
				<PlaceholderPictogram />
				<Text as="p">
					Quisque mattis orci et dui sagittis, quis molestie elit rhoncus. Sed
					id luctus nunc, in lacinia nulla. Etiam iaculis nisl sit amet diam
					auctor, eu ultricies nunc pellentesque.
				</Text>
				<CardLink href="#">Related action</CardLink>
			</Stack>
		</CardInner>
	</Card>

	<Card as="li" clickable shadow>
		<PlaceholderImage />
		<CardInner>
			<Stack gap={1}>
				<H3>
					<CardLink href="#">Clickable card title 4</CardLink>
				</H3>
				<Text as="p">
					Sed volutpat non enim ac efficitur. Etiam ut dolor tempor, tempor
					tortor at, luctus elit.
				</Text>
			</Stack>
		</CardInner>
	</Card>

	<Card as="li" clickable footerOutside shadow>
		<PlaceholderImage />
		<CardHeader>
			<H3>
				<CardLink href="#">Clickable card title 5</CardLink>
			</H3>
		</CardHeader>
		<CardInner>
			<Text as="p">
				Sed volutpat non enim ac efficitur. Etiam ut dolor tempor, tempor tortor
				at, luctus elit.
			</Text>
		</CardInner>
		<CardFooter>
			<TextLink href="#">Related action</TextLink>
		</CardFooter>
	</Card>
</Columns>

Colour

AgDS foreground components respond to the background colour of their parent container. When placed on a dark palette background, the dark palette variant of the component is displayed. When placed on a light palette background, the light palette variant is displayed.

This logic ensures sufficient contrast between foreground and background elements is maintained to meet WCAG 2.1 AA 4.5:1 contrast ratio for text (WCAG 1.4.3) and 3:1 for graphic elements that convey information (WCAG 1.4.11).

<Fragment>
	<Flex as="ul" gap={1.5} padding={1.5}>
		<Card as="li" shadow clickable>
			<CardInner>
				<Stack gap={1}>
					<Heading as="h3" type="h4">
						<CardLink href="#">Card light 1</CardLink>
					</Heading>
					<Text>
						Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras non
						finibus leo.
					</Text>
				</Stack>
			</CardInner>
		</Card>

		<Card as="li" shadow clickable>
			<CardInner>
				<Stack gap={1}>
					<Heading as="h3" type="h4">
						<CardLink href="#">Card light 2</CardLink>
					</Heading>
					<Text>
						Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras non
						finibus leo.
					</Text>
				</Stack>
			</CardInner>
		</Card>
	</Flex>

	<Flex as="ul" background="body" gap={1.5} padding={1.5} palette="dark">
		<Card as="li" clickable>
			<CardInner>
				<Stack gap={1}>
					<Heading as="h3" type="h4">
						<CardLink href="#">Card dark 1</CardLink>
					</Heading>
					<Text>
						Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras non
						finibus leo.
					</Text>
				</Stack>
			</CardInner>
		</Card>

		<Card as="li" clickable>
			<CardInner>
				<Stack gap={1}>
					<Heading as="h3" type="h4">
						<CardLink href="#">Card dark 2</CardLink>
					</Heading>
					<Text>
						Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras non
						finibus leo.
					</Text>
				</Stack>
			</CardInner>
		</Card>
	</Flex>
</Fragment>