Skip to main content
The Card component is a layout primitive for grouping related content with consistent styling.

Import

import { Card } from 'theme-ui'

Usage

<Card>
  <Heading>Card Title</Heading>
  <Text>Card content goes here.</Text>
</Card>

Props

variant
string
default:"'primary'"
Card variant from theme.cards. The component uses primary variant by default.
<Card variant="primary">Primary card</Card>
<Card variant="compact">Compact card</Card>
sx
ThemeUIStyleObject
Theme-aware styles for custom card appearance.
<Card
  sx={{
    p: 4,
    bg: 'background',
    borderRadius: 8,
    boxShadow: 'lg',
  }}
>
  Custom styled card
</Card>
as
React.ElementType
Render as a different HTML element. Defaults to div.
<Card as="article">Article card</Card>

Inherited Props

Card extends Box and accepts:
  • All standard HTML div attributes (or attributes for the element specified with as)
  • Box spacing props (m, p, mx, my, px, py, etc.)
  • Box color props (color, bg, opacity)

Composition

Cards are designed to be composed with other Theme UI components:
<Card>
  <Image src="/image.jpg" />
  <Heading>Card Title</Heading>
  <Text>Description text</Text>
  <Button>Action</Button>
</Card>

Examples

Basic Card

<Card>
  <Heading as="h3">Card Title</Heading>
  <Text>This is a basic card with some content.</Text>
</Card>

Card with Image

<Card>
  <Image src="/thumbnail.jpg" alt="Thumbnail" />
  <Box p={3}>
    <Heading as="h3">Product Name</Heading>
    <Text>Product description goes here.</Text>
    <Button mt={2}>View Details</Button>
  </Box>
</Card>

Interactive Card

<Card
  sx={{
    cursor: 'pointer',
    transition: 'transform 0.2s',
    '&:hover': {
      transform: 'translateY(-4px)',
      boxShadow: 'lg',
    },
  }}
>
  <Heading>Hover Me</Heading>
  <Text>This card lifts on hover.</Text>
</Card>

Card Grid

<Grid columns={[1, 2, 3]} gap={4}>
  <Card>
    <Heading>Card 1</Heading>
    <Text>Content</Text>
  </Card>
  <Card>
    <Heading>Card 2</Heading>
    <Text>Content</Text>
  </Card>
  <Card>
    <Heading>Card 3</Heading>
    <Text>Content</Text>
  </Card>
</Grid>
<Card>
  <Box p={3}>
    <Heading>Article Title</Heading>
    <Text>Article preview text...</Text>
  </Box>
  <Flex
    sx={{
      borderTop: '1px solid',
      borderColor: 'muted',
      p: 3,
      justifyContent: 'space-between',
    }}
  >
    <Text>Author Name</Text>
    <Text>2 min read</Text>
  </Flex>
</Card>

Clickable Card

<Card as="a" href="/article" sx={{ textDecoration: 'none', color: 'inherit' }}>
  <Heading>Article Title</Heading>
  <Text>Click anywhere on this card to navigate.</Text>
</Card>

Card with Badge

<Card sx={{ position: 'relative' }}>
  <Box
    sx={{
      position: 'absolute',
      top: 2,
      right: 2,
      bg: 'primary',
      color: 'white',
      px: 2,
      py: 1,
      borderRadius: 4,
      fontSize: 0,
    }}
  >
    New
  </Box>
  <Heading>Product Name</Heading>
  <Text>Product details</Text>
</Card>

Build docs developers (and LLMs) love