Skip to content

Action Buttons

GradientButton and FloatingActionButton are opinionated button wrappers for polished product interfaces. They compose the core Button, so they keep Faststrap's normal button behavior, HTMX attributes, accessible labels, and type="button" default.

Quick Start

from faststrap import FloatingActionButton, GradientButton

GradientButton("Launch", gradient="blue", href="/start")

FloatingActionButton(
    icon="plus",
    variant="success",
    position="bottom-right",
    label="Create item",
    hx_get="/items/new",
    hx_target="#modal",
)

GradientButton

Use GradientButton when you want a stronger call-to-action than a default Bootstrap button.

Parameter Type Default Description
*children Any required Button content.
gradient purple \| blue \| green \| orange \| pink \| str purple Preset or custom CSS gradient. All presets keep ≥3:1 contrast (WCAG non-text/UI) against the default white label.
size sm \| lg \| None None Bootstrap button size.
text_color str \| None None Label color override for light gradients (via --faststrap-gradient-button-text).
hover default \| lift \| glow \| none default Hover treatment.
GradientButton("Start trial", gradient="linear-gradient(135deg, #111827, #22c55e)")
GradientButton("Buy now", gradient="orange", hover="lift")

FloatingActionButton

Use FloatingActionButton for a page-level primary action, especially in dashboard and mobile-first layouts.

Parameter Type Default Description
*children Any empty Optional visible content.
icon str \| None None Bootstrap icon name.
variant Bootstrap variant primary Button color.
position bottom-right \| bottom-left \| top-right \| top-left bottom-right Fixed viewport position.
label str \| None Primary action Accessible label.
size sm \| md \| lg lg Logical size via --fs-fab-size (44/48/56px).
offset int \| None 2rem inset Viewport inset in rem units via --fs-fab-inset; reduce on mobile.
shape circle \| pill circle pill renders an extended icon+label FAB.
FloatingActionButton(icon="plus", label="Add expense", size="sm", offset=4)
FloatingActionButton("Edit draft", icon="edit", shape="pill")

Notes

  • GradientButton and FloatingActionButton accept normal Button kwargs such as href, hx_get, hx_target, data_bs_toggle, and disabled.
  • hover="none" fully disables hover/focus treatment (no lift, glow, or brightness shift).
  • FloatingActionButton validates position, size, and shape at render time and raises ValueError for unknown values.
  • faststrap-visual.css is loaded automatically by add_bootstrap().

API Reference

faststrap.components.forms.action_buttons.GradientButton(*children, gradient=UNSET, size=UNSET, text_color=None, hover='default', **kwargs)

Render a Bootstrap-compatible button with a gradient surface.

Parameters:

Name Type Description Default
*children Any

Button content.

()
gradient GradientPreset | str | None

Preset name or a raw CSS linear-gradient(...) value.

UNSET
size SizeType | None

Core Button size.

UNSET
text_color str | None

Override for the label color. Set this when a preset's light end would otherwise fail contrast against white text.

None
hover GradientHover

Hover treatment: default (subtle brightness), lift (translate + shadow), glow (focus-style ring), or none.

'default'
**kwargs Any

Additional Button kwargs (cls, css_vars, hx-*, ...).

{}
Source code in src/faststrap/components/forms/action_buttons.py
@register(category="forms")
@beta
def GradientButton(
    *children: Any,
    gradient: GradientPreset | str | None = UNSET,
    size: SizeType | None = UNSET,
    text_color: str | None = None,
    hover: GradientHover = "default",
    **kwargs: Any,
) -> Any:
    """Render a Bootstrap-compatible button with a gradient surface.

    Args:
        *children: Button content.
        gradient: Preset name or a raw CSS ``linear-gradient(...)`` value.
        size: Core ``Button`` size.
        text_color: Override for the label color. Set this when a preset's
            light end would otherwise fail contrast against white text.
        hover: Hover treatment: ``default`` (subtle brightness), ``lift``
            (translate + shadow), ``glow`` (focus-style ring), or ``none``.
        **kwargs: Additional ``Button`` kwargs (cls, css_vars, hx-*, ...).
    """
    cfg = resolve_defaults("GradientButton", gradient=gradient, size=size)
    c_gradient = cfg.get("gradient") or "purple"
    c_size = cast(SizeType | None, cfg.get("size"))
    gradient_value = GRADIENT_PRESETS.get(str(c_gradient), str(c_gradient))

    user_cls = kwargs.pop("cls", "")
    # Copy before mutating so callers can safely reuse their css_vars dict.
    css_vars = {**(kwargs.pop("css_vars", {}) or {})}
    css_vars["--faststrap-gradient-button-bg"] = gradient_value
    if text_color:
        css_vars["--faststrap-gradient-button-text"] = text_color

    classes = ["faststrap-gradient-button"]
    if hover == "lift":
        classes.append("hover-lift")
    elif hover == "glow":
        classes.append("hover-glow")
    elif hover == "none":
        classes.append("hover-none")

    return Button(
        *children,
        size=c_size,
        variant="primary",
        cls=merge_classes(*classes, user_cls),
        css_vars=css_vars,
        **kwargs,
    )

faststrap.components.forms.action_buttons.FloatingActionButton(*children, icon=None, variant=UNSET, position=UNSET, label=UNSET, size=UNSET, offset=UNSET, shape=UNSET, **kwargs)

Render a fixed-position floating action button.

Parameters:

Name Type Description Default
*children Any

Optional text content; combine with shape="pill" for an extended FAB.

()
icon str | None

Bootstrap icon name for icon-only usage.

None
variant VariantType | None

Bootstrap color variant.

UNSET
position FabPosition | None

Fixed corner placement.

UNSET
label str | None

Accessible label (required meaningfully when icon-only).

UNSET
size FabSize | None

Logical size token driving the --fs-fab-size CSS variable (sm=44px, md=48px, lg=56px). Default keeps the historical 56px circle.

UNSET
offset int | None

Inset from the viewport edge in spacing units (1 unit = --bs-spacer ≈ 1rem), driving --fs-fab-inset. Reduce for tighter mobile layouts.

UNSET
shape FabShape | None

circle (default) or pill for extended icon+label FABs.

UNSET
**kwargs Any

Additional Button kwargs (cls, css_vars, hx-*, style, ...).

{}
Source code in src/faststrap/components/forms/action_buttons.py
@register(category="forms")
@beta
def FloatingActionButton(
    *children: Any,
    icon: str | None = None,
    variant: VariantType | None = UNSET,
    position: FabPosition | None = UNSET,
    label: str | None = UNSET,
    size: FabSize | None = UNSET,
    offset: int | None = UNSET,
    shape: FabShape | None = UNSET,
    **kwargs: Any,
) -> Any:
    """Render a fixed-position floating action button.

    Args:
        *children: Optional text content; combine with ``shape="pill"`` for an
            extended FAB.
        icon: Bootstrap icon name for icon-only usage.
        variant: Bootstrap color variant.
        position: Fixed corner placement.
        label: Accessible label (required meaningfully when icon-only).
        size: Logical size token driving the ``--fs-fab-size`` CSS variable
            (``sm``=44px, ``md``=48px, ``lg``=56px). Default keeps the
            historical 56px circle.
        offset: Inset from the viewport edge in spacing units (1 unit =
            ``--bs-spacer`` ≈ 1rem), driving ``--fs-fab-inset``. Reduce for
            tighter mobile layouts.
        shape: ``circle`` (default) or ``pill`` for extended icon+label FABs.
        **kwargs: Additional ``Button`` kwargs (cls, css_vars, hx-*, style, ...).
    """
    if (
        position is not UNSET
        and position is not None
        and str(position) not in get_args(FabPosition)
    ):
        raise ValueError(f"position must be one of {get_args(FabPosition)}, got {position!r}")
    if size is not UNSET and size is not None and str(size) not in get_args(FabSize):
        raise ValueError(f"size must be one of {get_args(FabSize)}, got {size!r}")
    if shape is not UNSET and shape is not None and str(shape) not in get_args(FabShape):
        raise ValueError(f"shape must be one of {get_args(FabShape)}, got {shape!r}")

    cfg = resolve_defaults(
        "FloatingActionButton",
        variant=variant,
        position=position,
        label=label,
        size=size,
        offset=offset,
        shape=shape,
    )
    c_variant = cast(VariantType, cfg.get("variant") or "primary")
    c_position = cfg.get("position") or "bottom-right"
    c_label = cfg.get("label") or "Primary action"
    c_size = cast(FabSize | None, cfg.get("size")) or "lg"
    c_offset = cfg.get("offset")
    c_shape = cast(FabShape, cfg.get("shape") or "circle")

    user_cls = kwargs.pop("cls", "")
    fab_classes = ["faststrap-floating-action-button"]
    if c_shape == "pill":
        fab_classes.append("fab-pill")
    else:
        fab_classes.append("rounded-circle")
    fab_classes.append(f"fab-{c_position}")

    css_vars = {**(kwargs.pop("css_vars", {}) or {})}
    css_vars.setdefault("--fs-fab-size", f"{_FAB_SIZE_PX.get(str(c_size), 56)}px")
    if c_offset is not None:
        css_vars["--fs-fab-inset"] = f"{c_offset}rem"

    kwargs["css_vars"] = css_vars

    return Button(
        *children,
        variant=c_variant,
        icon=icon,
        cls=merge_classes(*fab_classes, user_cls),
        aria_label=c_label,
        **kwargs,
    )