Skip to content
ts
import Card from "@ui/Card.vue"

Card

Organize textual information, links, and interactive buttons in card-sized sections

ts
const props = defineProps<{
  title: string
  category?: true | 'h1' | 'h2' | 'h3' | 'h4' | 'h5'

  tags?: string[]
  image?: string | { src: string, style?: 'withPadding', label?: string }
  icon?: string

  flat?: true

  alertProps?: AlertProps
} & Partial<RouterLinkProps>
  &(PastelProps | ColorProps | DefaultProps)
  & RaisedProps
  & VariantProps
  & WidthProps
  >()

Add a :to prop, either containing an external link ("https://...") or a Vue Router destination:

Link
template
<Card
  title="Link"
  to="https://funkwhale.audio"
/>

If you add interactive elements, only the surrounding surfaces will be linked.

Avoid overlapping interactive elements

Avoid adding buttons and links on top of a linked card. This is an uncommon pattern and will confuse users.

template
<Alert red>
  <Card
    full
    primary
    title="Linked card with interactive elements (confusing)"
    to="./card.md"
    :tags="['rock', 'folk', 'punk']"
    icon="bi-exclamation large"
  >
    <Button
      low-height
      :on-click="()=>alert('Button clicked')"
    >
      Click me!
    </Button>

    <Link
      to="./card.md"
      align-text="end"
    >
      Open this file in a new window
    </Link>
  </Card>
</Alert>

<Alert>
  <Card
    full
    title="Card with interactive elements (better)"
    :tags="['rock', 'folk', 'punk']"
    icon="bi-check-lg large"
  >
    <Button
      secondary
      low-height
      :on-click="()=>alert('Button clicked')"
    >
      Click me!
    </Button>

    <Link
      secondary
      to="./card.md"
      align-text="end"
    >
      Open this file in a new window
    </Link>
    <template #action>
      <Link
        solid
        grow
        primary
        to="./card.md"
        align-text="center"
      >
        Go!
      </Link>
    </template>
  </Card>
</Alert>

Card as a Category header

Category cards are basic cards that contain only a title. To create a category card, pass a category prop.

My Favorites
...

What others listen to

...

Choosing the right heading level

Make sure to implement accessible heading trees. Do not skip heading levels (h1..h7).

The default title will be rendered as a h6. To override, set category="h3". Note that this behavior will change in the next update.

template
<Card
  flat
  solid
  purple
  category
  min-content
  title="My Favorites"
/>...
<Card
  category="h1"
  title="What others listen to"
/>...

INFO

For details on link behavior, consult the Vue Router docs on RouterLink.

Add an Image

Pass an image source to the image prop or set both image.src and image.style by passing an object.

INFO

Make sure to pass a label parameter to the image prop unless it is purely decorative.

For music lovers
Funkwhale users rejoice
For music lovers
template
<Card
  small
  title="For music lovers"
  image="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb"
/>
<Card
  title="For music lovers"
  :image="{
    src: 'https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb',
    style: 'withPadding',
    label: 'Funkwhale users rejoice'
  }"
/>

Add an Icon

Uploading...
template
<Card
  title="Uploading..."
  image="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb"
  icon="bi-cloud-arrow-up-fill"
/>

You can combine this prop with any other prop configuration. If you combine it with an image, keep an eye on the contrast ratio between the icon color and the image.

Add an Alert

INFO

To add props to the alert, add the alert-props property to the card. Check out the Alert component docs to find out which props are supported;

Your Collection
template
<Card
  title="Your Collection"
  :alert-props="{ red: true }"
>
  <template #alert>
    Please annotate all items with the required metadata.
  </template>
</Card>

Use slots

Topright action
Contextual actions go to the top-right of the Card.
Footer
Items in the footer region are secondary and will be displayed smaller than the main content.
Call-to-Action
Large Buttons or links at the bottom edge of the card serve as Call-to-Actions (CTA).
Multiple actions
If there are multiple actions, they will be presented in a row.
template
<Card title="Topright action">
  Contextual actions go to the top-right of the Card.
  <template #topright>
    <OptionsButton square-small />
  </template>
</Card>

<Card
  medium
  title="Footer"
>
  Items in the footer region are secondary and will be displayed smaller than the main content.
  <template #footer>
    <Button
      outline
      icon="bi-upload"
      @click="alert('Uploaded. Press OK!')"
    >
      Upload
    </Button>
    <Spacer style="flex-grow: 1" />
    <OptionsButton />
  </template>
</Card>

<Card
  medium
  title="Call-to-Action"
>
  Large Buttons or links at the bottom edge of the card serve as Call-to-Actions (CTA).
  <template #action>
    <Button
      secondary
      grow
      @click="alert('Open the pod picker')"
    >
      Action!
    </Button>
  </template>
</Card>

<Card
  full
  title="Multiple actions"
>
  If there are multiple actions, they will be presented in a row.
  <template #action>
    <Button
      secondary
      ghost
      min-content
      align-text="start"
      icon="bi-chevron-left"
    >
      Items
    </Button>
    <Spacer
      h
      grow
    />
    <Button
      primary
      @click="alert('Yay')"
    >
      OK
    </Button>
    <Button
      destructive
      @click="alert('Yay')"
    >
      Cancel
    </Button>
  </template>
</Card>

Add Tags

You can include tags on a card by adding a list of tags. These are rendered as pills.

For music lovers
Access your personal music collection from anywhere. Funkwhale gives you access to publication and sharing tools that you can use to promote your content across the web.
template
<Card
  medium
  title="For music lovers"
  :tags="['rock', 'folk', 'punk']"
>
  Access your personal music collection from anywhere.
  Funkwhale gives you access to publication and sharing tools
  that you can use to promote your content across the web.
</Card>

Differentiate mixed cards visually

Consider differentiating cards by color, size and shadow when mixing several of the following types:

  • Cards used for organizing the page spatially
  • Cards that represent objects
  • Interactive cards (buttons or links)

Add color

  • Choose a color: default, primary, secondary, destructive, or a Pastel (red, yellow, purple, green or blue)
  • Choose a variant: raised, solid, outline,...

Read more: Using Color

Set size

large (304px), medium (208px), auto, small, ...

Read more: Using Width

Remove shadow

Use the flat attribute to remove the automatic shadow. This helps reduce visual noise and differentiates cards.

Using this component

A11y Checklist

Accessible card

template
<Card
  title="Card"
  :category="level"
  :image="{
    src: whales,
    label: 'Colorful whales communicating in a network'
  }"
  :tags="['Tag']"
  icon="bi-check-lg"
>
  <Link to="https://funkwhale.audio">
    Inline link
  </Link>
  <template #action>
    <Link
      solid
      grow
      to="./"
    >
      Action link
    </Link>
  </template>
</Card>
<Card
  to="./"
  title="Link"
  :category="level"
>
  <template #topright>
    <OptionsButton
      title="More"
      aria-label="Toggle Card menu"
      @click.stop.prevent="toggleMenu"
    />
  </template>
</Card>

Test this example in isolation against WCAG2 criteria