Skip to content

Card

Cards are flexible and extensible content containers. They include options for headers and footers, a wide variety of content, contextual background colors, and powerful display options.

Bootstrap Reference

Bootstrap 5 Card Documentation


Quick Start

Live Preview
Featured
A simple card with some content.
Card(
    "A simple card with some content.",
    header="Featured",
    footer=Button("Go somewhere")
)

Visual Examples & Use Cases

1. Images & Structure

Cards commonly contain images at the top (img_top) or bottom (img_bottom).

Live Preview
...
Card Image Cap

Some quick example text to build on the card title.

Card(
    "Some quick example text to build on the card title.",
    title="Card Image Cap",
    img_top="https://placehold.co/600x400",
    footer="Last updated 3 mins ago"
)

2. Semantic Variants

Apply background colors with text-bg-{variant} classes by using the variant argument.

Code & Output

Live Preview
Success

Success Card

Error

Danger Card

Dark

Dark Card

Card("Success Card", title="Success", variant="success")
Card("Danger Card", title="Error", variant="danger")
Card("Dark Card", title="Dark", variant="dark")

3. Slot Class Customization 🛠️

FastStrap Cards have specialized "slots" for customization. You don't have to overwrite the base classes; just inject your own into specific parts.

Slot Param Targeting Description
header_cls .card-header Styles the header container.
body_cls .card-body Styles the main content area.
footer_cls .card-footer Styles the footer.
title_cls .card-title Styles the H5 title.
Live Preview
My Title
Content...
# A card with a blue header and padded body
Card(
    "Content...",
    header="My Title",
    header_cls="bg-primary text-white text-center",
    body_cls="p-5 fs-4"
)

Parameter Reference

faststrap.components.display.card.Card(*children, title=None, subtitle=None, header=None, footer=None, img_top=None, img_bottom=None, img_overlay=False, header_cls=None, body_cls=None, footer_cls=None, title_cls=None, subtitle_cls=None, text_cls=None, **kwargs)

Bootstrap Card component for flexible content containers.

Parameters:

Name Type Description Default
*children Any

Card body content

()
title str | None

Card title (styled with card-title)

None
subtitle str | None

Card subtitle (styled with card-subtitle)

None
header Any | None

Card header content (separate section above body)

None
footer Any | None

Card footer content (separate section below body)

None
img_top str | None

Image URL for top of card

None
img_bottom str | None

Image URL for bottom of card

None
img_overlay bool

Use image as background with overlay text

False
**kwargs Any

Additional HTML attributes (cls, id, hx-, data-, etc.)

{}

Returns:

Type Description
Div

FastHTML Div element with card structure

Example

Basic card:

Card("Card content", title="Card Title")

With header and footer:

Card( ... "Main content", ... title="Title", ... header="Featured", ... footer="Last updated 3 mins ago" ... )

Source code in src/faststrap/components/display/card.py
@register(category="display")
@stable
def Card(
    *children: Any,
    title: str | None = None,
    subtitle: str | None = None,
    header: Any | None = None,
    footer: Any | None = None,
    img_top: str | None = None,
    img_bottom: str | None = None,
    img_overlay: bool = False,
    header_cls: str | None = None,
    body_cls: str | None = None,
    footer_cls: str | None = None,
    title_cls: str | None = None,
    subtitle_cls: str | None = None,
    text_cls: str | None = None,
    **kwargs: Any,
) -> Div:
    """Bootstrap Card component for flexible content containers.

    Args:
        *children: Card body content
        title: Card title (styled with card-title)
        subtitle: Card subtitle (styled with card-subtitle)
        header: Card header content (separate section above body)
        footer: Card footer content (separate section below body)
        img_top: Image URL for top of card
        img_bottom: Image URL for bottom of card
        img_overlay: Use image as background with overlay text
        **kwargs: Additional HTML attributes (cls, id, hx-*, data-*, etc.)

    Returns:
        FastHTML Div element with card structure

    Example:
        Basic card:
        >>> Card("Card content", title="Card Title")

        With header and footer:
        >>> Card(
        ...     "Main content",
        ...     title="Title",
        ...     header="Featured",
        ...     footer="Last updated 3 mins ago"
        ... )
    """
    # Resolve defaults
    cfg = resolve_defaults(
        "Card",
        header_cls=header_cls,
        body_cls=body_cls,
        footer_cls=footer_cls,
    )

    c_title = title
    c_subtitle = subtitle
    c_header = header
    c_footer = footer
    c_img_top = img_top
    c_img_bottom = img_bottom
    c_img_overlay = img_overlay

    # CSS classes (fallback to empty string if None)
    c_header_cls = cfg.get("header_cls") or ""
    c_body_cls = cfg.get("body_cls") or ""
    c_footer_cls = cfg.get("footer_cls") or ""
    c_title_cls = title_cls or ""
    c_subtitle_cls = subtitle_cls or ""
    c_text_cls = text_cls or ""

    # Build base classes
    classes = ["card"]

    # Merge with user classes
    user_cls = kwargs.pop("cls", "")
    all_classes = merge_classes(" ".join(classes), user_cls)

    # Build attributes
    attrs: dict[str, Any] = {"cls": all_classes}
    attrs.update(convert_attrs(kwargs))

    # Build card structure
    parts = []

    # Add header if provided
    if c_header:
        parts.append(Div(c_header, cls=merge_classes("card-header", c_header_cls)))

    # Add top image
    if c_img_top and not c_img_overlay:
        parts.append(Img(src=c_img_top, cls="card-img-top", alt=""))

    # Build body content
    body_content = []

    # Add image for overlay mode
    if c_img_overlay and c_img_top:
        parts.append(Img(src=c_img_top, cls="card-img", alt=""))
        actual_body_cls = "card-img-overlay"
    else:
        actual_body_cls = "card-body"

    # Add title
    if c_title:
        body_content.append(H5(c_title, cls=merge_classes("card-title", c_title_cls)))

    # Add subtitle
    if c_subtitle:
        body_content.append(
            Div(c_subtitle, cls=merge_classes("card-subtitle mb-2 text-muted", c_subtitle_cls))
        )

    # Add main content
    if children:
        # If there's a title/subtitle, wrap content in P for better semantics
        if c_title or c_subtitle:
            body_content.append(Div(*children, cls=merge_classes("card-text", c_text_cls)))
        else:
            body_content.extend(children)

    # Add body
    if body_content:
        parts.append(Div(*body_content, cls=merge_classes(actual_body_cls, c_body_cls)))

    # Add bottom image
    if c_img_bottom and not c_img_overlay:
        parts.append(Img(src=c_img_bottom, cls="card-img-bottom", alt=""))

    # Add footer
    if c_footer:
        parts.append(Div(c_footer, cls=merge_classes("card-footer text-muted", c_footer_cls)))

    return Div(*parts, **attrs)