Skip to content

Table

The Table component enables you to display tabular data efficiently. FastStrap's implementation decomposes the table into semantic sub-components (THead, TBody, TRow, TCell) for maximum flexibility, while providing high-level arguments for common styles like striping and hover effects.

For sorting, search, and pagination, see DataTable.

Naming update in v0.6.1

Table, THead, TBody, TRow, and TCell are unchanged and remain the primary API. Faststrap v0.6.1 adds optional aliases BsTable, BsTHead, BsTBody, BsTRow, and BsTCell for projects that mix Faststrap with FastHTML's native table elements.

  • Existing code can keep using Table / THead / TBody / TRow / TCell
  • New mixed-import code may prefer the Bs* aliases for clarity

Bootstrap Reference

Bootstrap 5 Tables


Quick Start

Live Preview
ID Name Role
1 Alice Admin
2 Bob User
Table(
    THead(TRow(TCell("ID"), TCell("Name"), TCell("Role"))),
    TBody(
        TRow(TCell("1"), TCell("Alice"), TCell("Admin")),
        TRow(TCell("2"), TCell("Bob"), TCell("User")),
    ),
    striped=True, hover=True
)

Styling Options

FastStrap exposes Bootstrap's powerful table modifiers as simple boolean arguments.

1. Variants & Themes

Use variant to color the entire table, or set striped / hover for readability.

Live Preview (Variants)
Header
Dark Striped Content
Header
Borderless Content
# Dark Mode Table
Table(..., variant="dark", striped=True)

# Borderless
Table(..., borderless=True)

2. Responsiveness

Tables can overflow on small screens. Wrap them in a responsive container automatically using the responsive argument.

# Enables horizontal scrolling on small devices
Table(..., responsive=True) # or responsive="sm", "md", "lg"

3. DataFrame Builder (Beta)

Generate a table directly from pandas/polars or list-of-dict records:

import pandas as pd
from faststrap import Table

df = pd.DataFrame([
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
])

table = Table.from_df(
    df,
    striped=True,
    include_index=False,
    max_rows=100,
)

Supported inputs: - pandas DataFrame - polars DataFrame (if installed) - list[dict]

Optional Aliases for Mixed Imports

from faststrap import BsTable, BsTHead, BsTBody, BsTRow, BsTCell

BsTable(
    BsTHead(BsTRow(BsTCell("ID", header=True), BsTCell("Name", header=True))),
    BsTBody(BsTRow(BsTCell("1"), BsTCell("Alice"))),
    striped=True,
)

API Reference

faststrap.components.display.table.Table(*children, striped=False, striped_columns=False, bordered=False, borderless=False, hover=False, small=False, variant=None, responsive=False, caption_top=False, **kwargs)

Bootstrap Table component.

A responsive, styled table with support for striped rows, hover effects, borders, and color variants.

Parameters:

Name Type Description Default
*children Any

Table content (THead, TBody, or direct Tr elements)

()
striped bool

Add zebra-striping to rows

False
striped_columns bool

Add zebra-striping to columns

False
bordered bool

Add borders on all sides

False
borderless bool

Remove all borders

False
hover bool

Enable hover state on rows

False
small bool

Make table more compact

False
variant TableVariantType | None

Bootstrap color variant for table background

None
responsive bool | Literal['sm', 'md', 'lg', 'xl', 'xxl']

Make table horizontally scrollable. True for all breakpoints, or specify breakpoint (sm, md, lg, xl, xxl)

False
caption_top bool

Place caption at top of table

False
**kwargs Any

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

{}

Returns:

Type Description
Table | Div

FastHTML Table element, wrapped in Div if responsive

Examples:

Basic table:

>>> Table(
...     THead(TRow(TCell("Name", header=True), TCell("Age", header=True))),
...     TBody(TRow(TCell("Alice"), TCell("25")))
... )

Striped and hoverable:

>>> Table(
...     THead(...),
...     TBody(...),
...     striped=True,
...     hover=True
... )

Responsive with variant:

>>> Table(..., responsive=True, variant="dark")

Responsive at breakpoint:

>>> Table(..., responsive="lg")
See Also

Bootstrap docs: https://getbootstrap.com/docs/5.3/content/tables/

Source code in src/faststrap/components/display/table.py
@register(category="display")
@stable
def Table(
    *children: Any,
    striped: bool = False,
    striped_columns: bool = False,
    bordered: bool = False,
    borderless: bool = False,
    hover: bool = False,
    small: bool = False,
    variant: TableVariantType | None = None,
    responsive: bool | Literal["sm", "md", "lg", "xl", "xxl"] = False,
    caption_top: bool = False,
    **kwargs: Any,
) -> FTTable | Div:
    """Bootstrap Table component.

    A responsive, styled table with support for striped rows, hover effects,
    borders, and color variants.

    Args:
        *children: Table content (THead, TBody, or direct Tr elements)
        striped: Add zebra-striping to rows
        striped_columns: Add zebra-striping to columns
        bordered: Add borders on all sides
        borderless: Remove all borders
        hover: Enable hover state on rows
        small: Make table more compact
        variant: Bootstrap color variant for table background
        responsive: Make table horizontally scrollable. True for all breakpoints,
                   or specify breakpoint (sm, md, lg, xl, xxl)
        caption_top: Place caption at top of table
        **kwargs: Additional HTML attributes (cls, id, hx-*, data-*, etc.)

    Returns:
        FastHTML Table element, wrapped in Div if responsive

    Examples:
        Basic table:
        >>> Table(
        ...     THead(TRow(TCell("Name", header=True), TCell("Age", header=True))),
        ...     TBody(TRow(TCell("Alice"), TCell("25")))
        ... )

        Striped and hoverable:
        >>> Table(
        ...     THead(...),
        ...     TBody(...),
        ...     striped=True,
        ...     hover=True
        ... )

        Responsive with variant:
        >>> Table(..., responsive=True, variant="dark")

        Responsive at breakpoint:
        >>> Table(..., responsive="lg")

    See Also:
        Bootstrap docs: https://getbootstrap.com/docs/5.3/content/tables/
    """
    # Build table classes
    classes = ["table"]

    if striped:
        classes.append("table-striped")

    if striped_columns:
        classes.append("table-striped-columns")

    if bordered:
        classes.append("table-bordered")

    if borderless:
        classes.append("table-borderless")

    if hover:
        classes.append("table-hover")

    if small:
        classes.append("table-sm")

    if variant:
        classes.append(f"table-{variant}")

    if caption_top:
        classes.append("caption-top")

    # 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))

    # Create table
    table = FTTable(*children, **attrs)

    # Wrap in responsive container if needed
    if responsive:
        if responsive is True:
            responsive_cls = "table-responsive"
        else:
            responsive_cls = f"table-responsive-{responsive}"
        return Div(table, cls=responsive_cls)

    return table

faststrap.components.display.table.THead(*children, variant=None, **kwargs)

Bootstrap table header section.

Parameters:

Name Type Description Default
*children Any

Header rows (TRow elements)

()
variant TableVariantType | None

Bootstrap color variant for header background

None
**kwargs Any

Additional HTML attributes

{}

Returns:

Type Description
Thead

FastHTML Thead element

Examples:

>>> THead(
...     TRow(TCell("Name", header=True), TCell("Email", header=True)),
...     variant="dark"
... )
Source code in src/faststrap/components/display/table.py
@register(category="display")
@stable
def THead(
    *children: Any,
    variant: TableVariantType | None = None,
    **kwargs: Any,
) -> Thead:
    """Bootstrap table header section.

    Args:
        *children: Header rows (TRow elements)
        variant: Bootstrap color variant for header background
        **kwargs: Additional HTML attributes

    Returns:
        FastHTML Thead element

    Examples:
        >>> THead(
        ...     TRow(TCell("Name", header=True), TCell("Email", header=True)),
        ...     variant="dark"
        ... )
    """
    classes = []

    if variant:
        classes.append(f"table-{variant}")

    user_cls = kwargs.pop("cls", "")
    all_classes = merge_classes(" ".join(classes), user_cls) if classes else user_cls

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

    return Thead(*children, **attrs)

faststrap.components.display.table.TBody(*children, variant=None, divider=False, **kwargs)

Bootstrap table body section.

Parameters:

Name Type Description Default
*children Any

Body rows (TRow elements)

()
variant TableVariantType | None

Bootstrap color variant for body background

None
divider bool

Add a thicker border on top (table-group-divider)

False
**kwargs Any

Additional HTML attributes

{}

Returns:

Type Description
Tbody

FastHTML Tbody element

Examples:

>>> TBody(
...     TRow(TCell("Alice"), TCell("alice@example.com")),
...     TRow(TCell("Bob"), TCell("bob@example.com")),
...     divider=True
... )
Source code in src/faststrap/components/display/table.py
@register(category="display")
@stable
def TBody(
    *children: Any,
    variant: TableVariantType | None = None,
    divider: bool = False,
    **kwargs: Any,
) -> Tbody:
    """Bootstrap table body section.

    Args:
        *children: Body rows (TRow elements)
        variant: Bootstrap color variant for body background
        divider: Add a thicker border on top (table-group-divider)
        **kwargs: Additional HTML attributes

    Returns:
        FastHTML Tbody element

    Examples:
        >>> TBody(
        ...     TRow(TCell("Alice"), TCell("alice@example.com")),
        ...     TRow(TCell("Bob"), TCell("bob@example.com")),
        ...     divider=True
        ... )
    """
    classes = []

    if variant:
        classes.append(f"table-{variant}")

    if divider:
        classes.append("table-group-divider")

    user_cls = kwargs.pop("cls", "")
    all_classes = merge_classes(" ".join(classes), user_cls) if classes else user_cls

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

    return Tbody(*children, **attrs)

faststrap.components.display.table.TRow(*children, variant=None, active=False, **kwargs)

Bootstrap table row.

Parameters:

Name Type Description Default
*children Any

Row cells (TCell elements)

()
variant TableVariantType | None

Bootstrap color variant for row background

None
active bool

Highlight row as selected/active

False
**kwargs Any

Additional HTML attributes

{}

Returns:

Type Description
Tr

FastHTML Tr element

Examples:

>>> TRow(TCell("Data 1"), TCell("Data 2"), variant="success")
>>> TRow(TCell("Selected"), TCell("Row"), active=True)
Source code in src/faststrap/components/display/table.py
@register(category="display")
@stable
def TRow(
    *children: Any,
    variant: TableVariantType | None = None,
    active: bool = False,
    **kwargs: Any,
) -> Tr:
    """Bootstrap table row.

    Args:
        *children: Row cells (TCell elements)
        variant: Bootstrap color variant for row background
        active: Highlight row as selected/active
        **kwargs: Additional HTML attributes

    Returns:
        FastHTML Tr element

    Examples:
        >>> TRow(TCell("Data 1"), TCell("Data 2"), variant="success")
        >>> TRow(TCell("Selected"), TCell("Row"), active=True)
    """
    classes = []

    if variant:
        classes.append(f"table-{variant}")

    if active:
        classes.append("table-active")

    user_cls = kwargs.pop("cls", "")
    all_classes = merge_classes(" ".join(classes), user_cls) if classes else user_cls

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

    return Tr(*children, **attrs)

faststrap.components.display.table.TCell(*children, header=False, variant=None, active=False, colspan=None, rowspan=None, scope=None, **kwargs)

Bootstrap table cell (th or td).

Parameters:

Name Type Description Default
*children Any

Cell content

()
header bool

Render as th instead of td

False
variant TableVariantType | None

Bootstrap color variant for cell background

None
active bool

Highlight cell as selected/active

False
colspan int | None

Number of columns to span

None
rowspan int | None

Number of rows to span

None
scope Literal['row', 'col', 'rowgroup', 'colgroup'] | None

Scope for header cells (row, col, rowgroup, colgroup)

None
**kwargs Any

Additional HTML attributes

{}

Returns:

Type Description
Th | Td

FastHTML Th or Td element

Examples:

>>> TCell("Header", header=True, scope="col")
>>> TCell("Data", variant="warning")
>>> TCell("Wide Cell", colspan=2)
Source code in src/faststrap/components/display/table.py
@register(category="display")
@stable
def TCell(
    *children: Any,
    header: bool = False,
    variant: TableVariantType | None = None,
    active: bool = False,
    colspan: int | None = None,
    rowspan: int | None = None,
    scope: Literal["row", "col", "rowgroup", "colgroup"] | None = None,
    **kwargs: Any,
) -> Th | Td:
    """Bootstrap table cell (th or td).

    Args:
        *children: Cell content
        header: Render as th instead of td
        variant: Bootstrap color variant for cell background
        active: Highlight cell as selected/active
        colspan: Number of columns to span
        rowspan: Number of rows to span
        scope: Scope for header cells (row, col, rowgroup, colgroup)
        **kwargs: Additional HTML attributes

    Returns:
        FastHTML Th or Td element

    Examples:
        >>> TCell("Header", header=True, scope="col")
        >>> TCell("Data", variant="warning")
        >>> TCell("Wide Cell", colspan=2)
    """
    classes = []

    if variant:
        classes.append(f"table-{variant}")

    if active:
        classes.append("table-active")

    user_cls = kwargs.pop("cls", "")
    all_classes = merge_classes(" ".join(classes), user_cls) if classes else user_cls

    attrs: dict[str, Any] = {}
    if all_classes:
        attrs["cls"] = all_classes

    if colspan:
        attrs["colspan"] = str(colspan)

    if rowspan:
        attrs["rowspan"] = str(rowspan)

    if scope and header:
        attrs["scope"] = scope

    attrs.update(convert_attrs(kwargs))

    if header:
        return Th(*children, **attrs)
    return Td(*children, **attrs)