Skip to main content
The BCard component is a molecule that extends Nuxt UI’s UCard with additional layout features. It supports expandable body content, optional footer dividers, and flexible slot composition.

Props

as
string
default:"article"
The HTML tag to render the card as
variant
CardVariant
default:"outline"
The visual variant of the card. Derived from UCard component.
hasBodyExpanded
boolean
default:"false"
Whether the card body should expand to fill available vertical space using CSS Grid
Whether to show a divider border above the footer

Slots

default
Main content area of the card body
header
Content for the card header section
Content for the card footer section

Type Exports

export type CardVariant = InstanceType<typeof UCard>['$props']['variant']

Usage

Basic Card

<template>
  <BCard>
    <p>This is the card body content</p>
  </BCard>
</template>
<template>
  <BCard>
    <template #header>
      <h3>Card Title</h3>
    </template>
    
    <p>Main content goes here</p>
    
    <template #footer>
      <button>Action</button>
    </template>
  </BCard>
</template>

Expanded Body Layout

<template>
  <BCard has-body-expanded class="h-96">
    <template #header>
      <h3>Scrollable Content</h3>
    </template>
    
    <div class="overflow-y-auto">
      <p v-for="i in 50" :key="i">Line {{ i }}</p>
    </div>
    
    <template #footer>
      <button>Save</button>
    </template>
  </BCard>
</template>
<template>
  <BCard :has-footer-divider="false">
    <p>Content</p>
    
    <template #footer>
      <span>Footer without divider</span>
    </template>
  </BCard>
</template>

Different Variants

<template>
  <div class="grid gap-4">
    <BCard variant="outline">
      <p>Outline variant</p>
    </BCard>
    
    <BCard variant="solid">
      <p>Solid variant</p>
    </BCard>
  </div>
</template>

Custom Element Type

<template>
  <BCard as="section">
    <header>Section Card</header>
    <p>Rendered as a section element</p>
  </BCard>
</template>

Styling System

The component uses computed styles that adapt based on props:
const uiStyles = computed(() => {
  const baseStyles = {
    root: '',
    header: 'p-0 sm:p-0',
    body: 'p-0 sm:p-0',
    footer: 'p-0 sm:p-0 sm:px-0',
  }

  // Apply hasBodyExpanded styles
  if (props.hasBodyExpanded) {
    baseStyles.root = 'grid h-full grid-rows-[auto_1fr_auto]'
    baseStyles.body = twMerge(baseStyles.body, 'overflow-y-auto')
  }

  // Apply hasFooterDivider styles
  if (!props.hasFooterDivider) {
    baseStyles.body = twMerge(baseStyles.body, 'border-none')
  }

  return baseStyles
})

Layout Behavior

When hasBodyExpanded is true:
  • Card root becomes a CSS Grid container
  • Layout uses grid-rows-[auto_1fr_auto] to make body expand
  • Header and footer have fixed height
  • Body fills remaining space and can scroll if needed
Source: /home/daytona/workspace/source/app/components/b/card/b-card.vue:81

Build docs developers (and LLMs) love