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.
The HTML tag to render the card as
variant
CardVariant
default:"outline"
The visual variant of the card. Derived from UCard component.
Whether the card body should expand to fill available vertical space using CSS Grid
Whether to show a divider border above the footer
Main content area of the card body
Content for the card header section
Content for the card footer section
Type Exports
export type CardVariant = InstanceType<typeof UCard>['$props']['variant']
Basic Card
<template>
<BCard>
<p>This is the card body content</p>
</BCard>
</template>
Card with Header and Footer
<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