Skip to main content
Since Shoelace 2.0 Code stable Pattern stable Figma draft

Card

<sl-card> | SlCard

Cards can be used to group related subjects in a container.

Examples

Basic Card

Basic cards aren’t very exciting, but they can display any content you want them to.

This is just a basic card. No image, no header, and no footer. Just your content.
<sl-card class="card-basic">
  This is just a basic card. No image, no header, and no footer. Just your content.
</sl-card>

<style>
  .card-basic {
    max-width: 300px;
  }
</style>
sl-card.card-basic
  | This is just a basic card. No image, no header, and no footer. Just your content.

css:
  .card-basic {
    max-width: 300px;
  }
import SlCard from '@teamshares/shoelace/dist/react/card';

const css = `
  .card-basic {
    max-width: 300px;
  }
`;

const App = () => (
  <>
    <SlCard className="card-basic">
      This is just a basic card. No image, no header, and no footer. Just your content.
    </SlCard>

    <style>{css}</style>
  </>
);

Card with No Shadow

Use the noShadow property to remove a card’s default box shadow.

This is just a basic card with no shadow.
<sl-card class="card-basic" noShadow> This is just a basic card with no shadow. </sl-card>

<style>
  .card-basic {
    max-width: 300px;
  }
</style>
sl-card.card-basic noShadow=true
  |   This is just a basic card with no shadow.

css:
  .card-basic {
    max-width: 300px;
  }
import { SlCard } from '@teamshares/shoelace/dist/react';

const css = `
  .card-basic {
    max-width: 300px;
  }
`;

const App = () => (
  <>
    <SlCard className="card-basic" noShadow>
      This is just a basic card with no shadow.
    </SlCard>

    <style>{css}</style>
  </>
);

Card with Header

Headers can be used to display titles, actions, and more. Other than padding and a bottom border, headers have no styling applied by default.

Card header
This card has a header. You can put all sorts of things in it!
<sl-card class="card-header">
  <div slot="header">
    Card header
    <sl-icon-button library="fa" name="fas-pencil" label="Edit settings"></sl-icon-button>
  </div>

  This card has a header. You can put all sorts of things in it!
</sl-card>

<style>
  .card-header {
    max-width: 300px;
  }

  .card-header [slot='header'] {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

.card-header sl-icon-button {
    font-size: var(--sl-font-size-medium);
  }
</style>
sl-card.card-header
  div slot="header"
    | Card header
    sl-icon-button library="fa" name="fas-pencil" label="Edit settings"
  | This card has a header. You can put all sorts of things in it!

css:
  .card-header {
    max-width: 300px;
  }

  .card-header [slot=header] {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .card-header sl-icon-button {
    font-size: var(--sl-font-size-medium);
  }
import SlCard from '@teamshares/shoelace/dist/react/card';
import SlIconButton from '@teamshares/shoelace/dist/react/icon-button';

const css = `
  .card-header {
    max-width: 300px;
  }

  .card-header [slot="header"] {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .card-header sl-icon-button {
    font-size: var(--sl-font-size-medium);
  }
`;

const App = () => (
  <>
    <SlCard className="card-header">
      <div slot="header">
        Card header
        <SlIconButton library="fa" name="fas-pencil"></SlIconButton>
      </div>
      This card has a header. You can put all sorts of things in it!
    </SlCard>

    <style>{css}</style>
  </>
);

Footers can be used to display actions, summaries, or other relevant content. Similar to the header, footers have no styling applied by default other than padding and a top border.

This card has a footer. You can put all sorts of things in it!
Previous Next
<sl-card class="card-footer">
  This card has a footer. You can put all sorts of things in it!

  <div slot="footer">
    <sl-button variant="default">Previous</sl-button>
    <sl-button variant="primary">Next</sl-button>
  </div>
</sl-card>

<style>
  .card-footer {
    max-width: 300px;
  }

  .card-footer [slot='footer'] {
    display: flex;
    justify-content: flex-end;
    align-items: center;
  }

  .card-footer [slot='footer'] > * {
    margin-inline-start: 0.5rem;
  }
</style>
sl-card.card-footer
  | This card has a footer. You can put all sorts of things in it!
  div slot="footer"
    sl-rating
    sl-button variant="primary" Preview

css:
  .card-footer {
    max-width: 300px;
  }

  .card-footer [slot=footer] {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .card-footer [slot='footer'] > * {
    margin-inline-start: 0.5rem;
  }
import SlButton from '@teamshares/shoelace/dist/react/button';
import SlCard from '@teamshares/shoelace/dist/react/card';
import SlRating from '@teamshares/shoelace/dist/react/rating';

const css = `
  .card-footer {
    max-width: 300px;
  }

  .card-footer [slot="footer"] {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .card-footer [slot='footer'] > * {
  margin-inline-start: 0.5rem;
  }
`;

const App = () => (
  <>
    <SlCard className="card-footer">
      This card has a footer. You can put all sorts of things in it!
      <div slot="footer">
        <SlRating></SlRating>
        <SlButton slot="footer" variant="primary">
          Preview
        </SlButton>
      </div>
    </SlCard>

    <style>{css}</style>
  </>
);

Images

Cards accept an image slot. The image is displayed atop the card and stretches to fit.

A kitten walks towards camera on top of pallet. This is a kitten, but not just any kitten. This kitten likes walking along pallets.
<sl-card class="card-image">
  <img
    slot="image"
    src="https://images.unsplash.com/photo-1547191783-94d5f8f6d8b1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=80"
    alt="A kitten walks towards camera on top of pallet."
  />
  This is a kitten, but not just any kitten. This kitten likes walking along pallets.
</sl-card>

<style>
  .card-image {
    max-width: 300px;
  }
</style>
sl-card.card-image
  img slot="image" src="https://images.unsplash.com/photo-1547191783-94d5f8f6d8b1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=80" alt="A kitten walks towards camera on top of pallet."
  | This is a kitten, but not just any kitten. This kitten likes walking along pallets.

css:
  .card-image {
    max-width: 300px;
  }
import SlCard from '@teamshares/shoelace/dist/react/card';

const css = `
  .card-image {
    max-width: 300px;
  }
`;

const App = () => (
  <>
    <SlCard className="card-image">
      <img
        slot="image"
        src="https://images.unsplash.com/photo-1547191783-94d5f8f6d8b1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=80"
        alt="A kitten walks towards camera on top of pallet."
      />
      This is a kitten, but not just any kitten. This kitten likes walking along pallets.
    </SlCard>

    <style>{css}</style>
  </>
);

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.1.0/cdn/components/card/card.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.1.0/cdn/components/card/card.js';

To import this component using a bundler:

import '@shoelace-style/shoelace/dist/components/card/card.js';

To import this component as a React component:

import SlCard from '@shoelace-style/shoelace/dist/react/card';

Slots

Name Description
(default) The card’s main content.
header An optional header for the card.
footer An optional footer for the card.
image An optional image to render at the start of the card.

Learn more about using slots.

Properties

Name Description Reflects Type Default
noShadow Option to remove the card’s default box shadow. boolean false
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Custom Properties

Name Description Default
--border-color The card’s border color, including borders that occur inside the card.
--border-radius The border radius for the card’s edges.
--border-width The width of the card’s borders.
--padding The padding to use for the card’s sections.

Learn more about customizing CSS custom properties.

Parts

Name Description
base The component’s base wrapper.
image The container that wraps the card’s image.
header The container that wraps the card’s header.
body The container that wraps the card’s main content.
footer The container that wraps the card’s footer.

Learn more about customizing CSS parts.