Skip to contentShopify logoPolaris

Card

Cards are used to group similar concepts and tasks together to make Shopify easier for merchants to scan, read, and get things done.

Use when you have a simple message to communicate to merchants that doesn’t require any secondary steps.

import {Card} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Online store dashboard" sectioned>
      <p>View a summary of your online store’s performance.</p>
    </Card>
  );
}

Use for less important card actions, or actions merchants may do before reviewing the contents of the card. For example, merchants may want to add items to a card containing a long list, or enter a customer’s new address.

import {Card} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card sectioned title="Variants" actions={[{content: 'Add variant'}]}>
      <p>
        Add variants if this product comes in multiple versions, like different
        sizes or colors.
      </p>
    </Card>
  );
}

Use footer actions for a card’s most important actions, or actions merchants should do after reviewing the contents of the card. For example, merchants should review the contents of a shipment before an important action like adding tracking information. Footer actions can be left or right aligned with the footerActionAlignment prop.

import {Card, List} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card
      title="Shipment 1234"
      secondaryFooterActions={[{content: 'Edit shipment'}]}
      primaryFooterAction={{content: 'Add tracking number'}}
    >
      <Card.Section title="Items">
        <List>
          <List.Item>1 Ă— Oasis Glass, 4-Pack</List.Item>
          <List.Item>1 Ă— Anubis Cup, 2-Pack</List.Item>
        </List>
      </Card.Section>
    </Card>
  );
}

When multiple secondary footer actions are provided, they will render in an action list popover activated by a disclosure button. The disclosure button text can be customized with the secondaryFooterActionsDisclosureText prop.

import {Card, List} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card
      title="Shipment 1234"
      secondaryFooterActions={[
        {content: 'Cancel shipment', destructive: true},
        {content: 'Add another shipment', disabled: true},
      ]}
      primaryFooterAction={{content: 'Add tracking number'}}
    >
      <Card.Section title="Items">
        <List>
          <List.Item>1 Ă— Oasis Glass, 4-Pack</List.Item>
          <List.Item>1 Ă— Anubis Cup, 2-Pack</List.Item>
        </List>
      </Card.Section>
    </Card>
  );
}

Use to present actionable content that is optional or not the primary purpose of the page.

import {Card, Stack, ButtonGroup, Button} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Secure your account with 2-step authentication">
      <Card.Section>
        <Stack spacing="loose" vertical>
          <p>
            Two-step authentication adds an extra layer of security when logging
            in to your account. A special code will be required each time you
            log in, ensuring only you can access your account.
          </p>
          <Stack distribution="trailing">
            <ButtonGroup>
              <Button>Enable two-step authentication</Button>
              <Button plain>Learn more</Button>
            </ButtonGroup>
          </Stack>
        </Stack>
      </Card.Section>
    </Card>
  );
}

Use when a card action will delete merchant data or be otherwise difficult to recover from.

import {Card, List} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card
      title="Shipment 1234"
      secondaryFooterActions={[{content: 'Cancel shipment', destructive: true}]}
      primaryFooterAction={{content: 'Add tracking number'}}
    >
      <Card.Section title="Items">
        <List>
          <List.Item>1 Ă— Oasis Glass, 4-Pack</List.Item>
          <List.Item>1 Ă— Anubis Cup, 2-Pack</List.Item>
        </List>
      </Card.Section>
    </Card>
  );
}

Use when you have two related but distinct pieces of information to communicate to merchants. Multiple sections can help break up complicated concepts to make them easier to scan and understand.

import {Card} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Online store dashboard">
      <Card.Section>
        <p>View a summary of your online store’s performance.</p>
      </Card.Section>

      <Card.Section>
        <p>
          View a summary of your online store’s performance, including sales,
          visitors, top products, and referrals.
        </p>
      </Card.Section>
    </Card>
  );
}

Use when you have two related but distinct pieces of information to communicate to merchants that are complex enough to require a title to introduce them.

import {Card} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Online store dashboard">
      <Card.Section title="Reports">
        <p>View a summary of your online store’s performance.</p>
      </Card.Section>

      <Card.Section title="Summary">
        <p>
          View a summary of your online store’s performance, including sales,
          visitors, top products, and referrals.
        </p>
      </Card.Section>
    </Card>
  );
}

Use when your card section has actions that apply only to that section.

import {Card} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Customer">
      <Card.Section>
        <p>John Smith</p>
      </Card.Section>
      <Card.Section title="Contact Information" actions={[{content: 'Edit'}]}>
        <p>john.smith@example.com</p>
      </Card.Section>
    </Card>
  );
}

Use when your card sections need further categorization.

import {Card} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Customer">
      <Card.Section>
        <p>John Smith</p>
      </Card.Section>
      <Card.Section title="Addresses">
        <Card.Subsection>
          123 First St
          <br />
          Somewhere
          <br />
          The Universe
        </Card.Subsection>
        <Card.Subsection>
          123 Second St
          <br />
          Somewhere
          <br />
          The Universe
        </Card.Subsection>
      </Card.Section>
      <Card.Section>
        <Card.Subsection>
          A single subsection without a sibling has no visual appearance
        </Card.Subsection>
      </Card.Section>
    </Card>
  );
}

Use when a card action applies only to one section and will delete merchant data or be otherwise difficult to recover from.

import {Card} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Customer">
      <Card.Section>
        <p>John Smith</p>
      </Card.Section>
      <Card.Section
        title="Contact Information"
        actions={[{content: 'Delete', destructive: true}, {content: 'Edit'}]}
      >
        <p>john.smith@example.com</p>
      </Card.Section>
    </Card>
  );
}

Use to indicate when one of the sections in your card contains inactive or disabled content.

import {Card, List} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Staff accounts">
      <Card.Section>
        <List>
          <List.Item>Felix Crafford</List.Item>
          <List.Item>Ezequiel Manno</List.Item>
        </List>
      </Card.Section>

      <Card.Section subdued title="Deactivated staff accounts">
        <List>
          <List.Item>Felix Crafford</List.Item>
          <List.Item>Ezequiel Manno</List.Item>
        </List>
      </Card.Section>
    </Card>
  );
}

Use for content that you want to deprioritize. Subdued cards don’t stand out as much as cards with white backgrounds so don’t use them for information or actions that are critical to merchants.

import {Card, List} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card title="Deactivated staff accounts" sectioned subdued>
      <List>
        <List.Item>Felix Crafford</List.Item>
        <List.Item>Ezequiel Manno</List.Item>
      </List>
    </Card>
  );
}

Use to be able to use custom React elements as header content.

import {Card, Popover, Button, ActionList, List} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card>
      <Card.Header
        actions={[
          {
            content: 'Preview',
          },
        ]}
        title="Staff accounts"
      >
        <Popover
          active
          activator={
            <Button disclosure plain>
              Add account
            </Button>
          }
          onClose={() => {}}
        >
          <ActionList items={[{content: 'Member'}, {content: 'Admin'}]} />
        </Popover>
      </Card.Header>
      <Card.Section>
        <List>
          <List.Item>Felix Crafford</List.Item>
          <List.Item>Ezequiel Manno</List.Item>
        </List>
      </Card.Section>
    </Card>
  );
}

Use to render custom content such as icons, links, or buttons in a card section’s header.

import {Card, Stack, Icon, Subheading, List} from '@shopify/polaris';
import {ProductsMajor} from '@shopify/polaris-icons';
import React from 'react';

function CardExample() {
  return (
    <Card title="Products">
      <Card.Section
        title={
          <Stack>
            <Icon source={ProductsMajor} />
            <Subheading>New Products</Subheading>
          </Stack>
        }
      >
        <List>
          <List.Item>Socks</List.Item>
          <List.Item>Super Shoes</List.Item>
        </List>
      </Card.Section>
    </Card>
  );
}

Use as a broad example that includes most props available to card.

import {
  Card,
  Popover,
  Button,
  ActionList,
  TextContainer,
  ResourceList,
  Stack,
  List,
} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card
      secondaryFooterActions={[{content: 'Dismiss'}]}
      primaryFooterAction={{content: 'Export Report'}}
    >
      <Card.Header
        actions={[
          {
            content: 'Total Sales',
          },
        ]}
        title="Sales"
      >
        <Popover
          active={false}
          activator={
            <Button disclosure plain>
              View Sales
            </Button>
          }
          onClose={() => {}}
        >
          <ActionList
            items={[{content: 'Gross Sales'}, {content: 'Net Sales'}]}
          />
        </Popover>
      </Card.Header>
      <Card.Section>
        <TextContainer>
          You can use sales reports to see information about your customers’
          orders based on criteria such as sales over time, by channel, or by
          staff.
        </TextContainer>
      </Card.Section>
      <Card.Section title="Total Sales Breakdown">
        <ResourceList
          resourceName={{singular: 'sale', plural: 'sales'}}
          items={[
            {
              sales: 'Orders',
              amount: 'USD$0.00',
              url: 'reports/orders',
            },
            {
              sales: 'Returns',
              amount: '-USD$250.00',
              url: 'reports/returns',
            },
          ]}
          renderItem={(item) => {
            const {sales, amount, url} = item;
            return (
              <ResourceList.Item
                url={url}
                accessibilityLabel={`View Sales for ${sales}`}
              >
                <Stack>
                  <Stack.Item fill>{sales}</Stack.Item>
                  <Stack.Item>{amount}</Stack.Item>
                </Stack>
              </ResourceList.Item>
            );
          }}
        />
      </Card.Section>
      <Card.Section title="Deactivated reports" subdued>
        <List>
          <List.Item>Payouts</List.Item>
          <List.Item>Total Sales By Channel</List.Item>
        </List>
      </Card.Section>
      <Card.Section title="Note">
        <TextContainer>
          The sales reports are available only if your store is on the Shopify
          plan or higher.
        </TextContainer>
      </Card.Section>
    </Card>
  );
}

Use when you need further control over the spacing of your card sections.

import {Card, Image, TextContainer} from '@shopify/polaris';
import React from 'react';

function CardExample() {
  return (
    <Card>
      <Card.Section flush>
        <Image
          source="https://burst.shopifycdn.com/photos/black-orange-stripes_373x@2x.jpg"
          alt="a sheet with purple and orange stripes"
        />
      </Card.Section>
      <Card.Section subdued>
        <TextContainer>
          You can use sales reports to see information about your customers’
          orders based on criteria such as sales over time, by channel, or by
          staff.
        </TextContainer>
      </Card.Section>
    </Card>
  );
}

Props

Want to help make this feature better? Please share your feedback.

interface CardProps
title?React.ReactNode

Title content for the card.

children?React.ReactNode

Inner content of the card.

subdued?boolean

A less prominent card.

sectioned?boolean

Auto wrap content in section.

actions?[]

Card header actions.

primaryFooterAction?

Primary action in the card footer.

secondaryFooterActions?[]

Secondary actions in the card footer.

secondaryFooterActionsDisclosureText?string

The content of the disclosure button rendered when there is more than one secondary footer action.

footerActionAlignment?"left" | "right"

Alignment of the footer actions on the card, defaults to right.

hideOnPrint?boolean

Allow the card to be hidden when printing.

Best practices

Cards should:

  • Use headings that set clear expectations about the card’s purpose
  • Prioritize information so the content merchants most need to know comes first
  • Stick to single user flows or break more complicated flows into multiple sections
  • Avoid too many call-to-action buttons or links and only one primary call to action per card
  • Use calls to action on the bottom of the card for next steps and use the space in the upper right corner of the card for persistent, optional actions (such as an Edit link)

Content guidelines

Title

Card titles should follow the content guidelines for headings and subheadings.

Body content

Body content should be:

  • Actionable: start sentences with imperative verbs when telling merchants what actions are available to them (especially something new). Don’t use permissive language like “you can”.

Do

Get performance for all your sales channels.

Don’t

Now you can get performance data for all your sales channels.

  • Structured for merchant success: always put the most critical information first.
  • Clear: use the verb “need” to help merchants understand when they’re required to do something.

Do

To buy a shipping label, you need to enter the total weight of your shipment, including packaging.

Don’t

To buy a shipping label, you must enter the total weight of your shipment, including packaging.

Call-to-action button

Buttons should be:

  • Clear and predictable: merchants should be able to anticipate what will happen when they click a button. Never deceive merchants by mislabeling a button.

Do

  • Create order
  • Buy shipping label

Don’t

  • New order
  • Buy

Action-led: buttons should always lead with a strong verb that encourages action. To provide enough context to merchants use the {verb}+{noun} format on buttons except in the case of common actions like Save, Close, Cancel, or OK.

Do

  • Activate Apple Pay
  • View shipping settings

Don’t

  • Try Apple Pay
  • View your settings

Scannable: Avoid unnecessary words and articles such as the, an, or a.

Do

Add menu item

Don’t

Add a menu item

Section titles

Section titles should be:

  • Informative: they should label the type of content grouped in the body content below
  • Like headings: follow the same content guidelines as when you’re writing headings

Links should be:

  • Used for secondary or persistent actions: links should be used to represent lower priority actions than buttons, or persistent actions that merchants may take at any time (such as a persistent Edit link).
  • Clearly labeled: merchants should not need to guess where they’ll end up if they click on an action link. Never use “click here” as a link because it doesn’t set expectations about what’s next.
  • Similar to buttons: Follow the same content guidelines as when you’re writing text for buttons.


Accessibility

The required title prop gives the card a level 2 heading (<h2>). This helps with readability and provides structure to screen reader users.

If you use the subdued prop on a card or section, make sure that the card or section title conveys the reason for using subdued. This ensures that merchants with low vision, including those who use screen readers, can identify that the content is inactive or less important.

Do

Example
<Card title="Deactivated staff accounts" sectioned subdued>
  <List>
    <List.Item>Felix Crafford</List.Item>
    <List.Item>Ezequiel Manno</List.Item>
  </List>
</Card>

Don’t

Example
<Card title="Staff accounts" sectioned subdued>
  <List>
    <List.Item>Felix Crafford</List.Item>
    <List.Item>Ezequiel Manno</List.Item>
  </List>
</Card>