Skip to content
SproutAceve · v3.31.0
Overview What is your role? Connect to Sprout MCP reference Adopting Sprout
Brand & logos Color Typography Spacing & layout Elevation Iconography Accessibility
Overview Alert Avatar Badge Breadcrumb Buttons Cards Checkbox Data grid Dialog Dropdown button Fab button Floating tabs Inputs Menu Navigation Numeric input Progress bar Progress ring Radio button Ribbon toolbar Switch Tabs Tag Tooltip
Interaction & motion Voice & content Product patterns
AI patterns AI transparency & disclosure AI disclosure label
Design principles Personas Trust and ethics Meet the makers
Build the systemplay Tower of tokensplay Site runnerplay
How it works Changelogv3.31 Roadmap Contribute
Components

Fab button.

The Floating Action Button is the one primary action on a mobile surface — fixed near a screen edge, floating above content on the highest elevation layer Sprout has. A screen gets at most one. If a second action feels equally urgent, that is a sign the primary action was named wrong, not a reason to add a second FAB.

Try it

Type
Shape

Anatomy

An icon on its own for Standard and Mini; an icon plus a short label for Extended. No Type mixes a label with no icon.

Create order
Icon24px, always present — a FAB is never label-only. Communicates the action even before the label (Extended) or on its own (Standard, Mini).
LabelExtended only. One or two words, verb + noun when the action isn't obvious from the icon alone — "Create order", not just "Create".
ContainerPill (Round: yes) or a 16px / 8px squircle (Round: no) — see Specification. Fill is always var(--accent), never Outlined or Text like Buttons.
ElevationSits on the Floater layer — the same one as dialogs and toasts. See /elevation. No border; the fill and shadow are the only edge it needs.

Type & size

Three fixed sizes, not a S/M/L scale like Buttons — pick the Type that matches the surface, don't scale one to fit.

Standard
56 × 56px — icon only
Mini
40 × 40px — icon only, for a dense secondary surface
Create orderExtended
48px tall, hugs its label — icon + text

Standard is the default for a screen's one primary action. Mini is for a denser secondary surface (inside a panel, not the main screen) where a 56px target would crowd the content. Extended spends the extra width only when the action genuinely needs a label to be understood — don't reach for it just to fill space.

Elevation

The Floater layer — the same shadow as a dialog or a toast, and the reason a FAB never needs a border.

var(--shadow-floater) in light mode; in dark mode the shadow is inert and the lighter fill (var(--accent) flips to primary-300) does the lifting instead — the same light/dark mechanism documented in full on Shadow & elevation. Never add a second shadow or a border on top of it.

Placement

Fixed to a corner, clear of everything else that floats.

PositionBottom-right is conventional on LTR surfaces — bottom-left on RTL. Fixed to the viewport, not the scroll content.
Safe areaClear of the device safe area and any system chrome (home indicator, gesture bar).
With Floating tabsEach keeps its own corner. Leave at least 16px between the FAB and the tabs track — see /floating-tabs.
With another FABNever two. A screen gets one primary action; a second candidate goes in the ribbon, a menu, or waits for its own screen.
Over contentNever let it obscure the one piece of content or the one control the user came for — reserve bottom padding in the scroll area, same rule as Floating tabs.
Scroll behaviourStays fixed while content scrolls underneath it. It may hide on scroll-down and reappear on scroll-up on very short surfaces, but that is a product-level decision, not a default.

Do & don't

Do — use it for the single most important action on the screen — the one thing most people came to do.
Don't — place two FABs on one screen. Two competing "primary" actions means neither one is primary.
Create order
Do — reach for Extended when the icon alone would be ambiguous — a generic plus could mean several things.
Don't — ship an icon-only FAB with no aria-label. Without one, it has no accessible name at all — see Accessibility below.

Specification

Every value is a token, ported from the Figma component.

Standard56 × 56px — 16px padding + 24px icon. Pill (full radius) or var(--radius-4), 16px, when Round is off.
Mini40 × 40px — 8px padding + 24px icon. Pill, or var(--radius-3), 8px, when Round is off.
Extended48px tall — 12px top/bottom padding + 24px icon. 12px left / 20px right padding, 8px icon-to-label gap. Pill, or var(--radius-4), 16px, when Round is off.
Icon24px, always var(--accent-ink) — white on the light-mode green, dark ink on the dark-mode light-green fill.
Label (Extended)Manrope Bold 14px, var(--accent-ink), one line, no wrap.
Fillvar(--accent) — flips to primary-300 in dark mode so a dark icon stays legible without changing the token.
Shadowvar(--shadow-floater) — Floater layer. Inert in dark mode; the lighter fill carries the lift instead.
BorderNone in any state — the fill already clears 3:1 against the page in both themes.

Accessibility

Accessible nameStandard and Mini show only an icon — they need a real aria-label describing the action ("Create order"), never just the bare glyph. Extended's visible label already provides one; don't duplicate it with a redundant aria-label.
ElementA real <button>, so Tab reaches it and Enter / Space activate it by default.
Focus visibleStandard focus ring — never suppressed to "clean up" the circle.
Reachable without a FABThe action the FAB performs must also exist somewhere else reachable by keyboard-only and screen-reader users who may not discover a fixed-position control — a ribbon command or a menu item, typically.
ColourFill colour carries no meaning beyond "this is the primary action" — never use it to signal severity the way Danger does on Buttons.
MotionIf a FAB animates in on scroll, respect prefers-reduced-motion — appear instantly instead of sliding or fading.

Props (React)

Proposal — no React primitive ships yet. This is the target shape, not an import.

type FabButtonProps = {
  type?: "standard" | "mini" | "extended";  // default "standard" — fixed sizes, not S/M/L
  round?: boolean;                          // default true — pill/circle vs a squircle
  icon: IconName;                           // 24px, required — a FAB is never icon-less
  label?: ReactNode;                        // "extended" only; ignored otherwise
  "aria-label": string;                     // required when type !== "extended"
  onClick: () => void;
};
← PreviousDropdown buttonNext →Floating tabs
Sprout · Aceve Design System · v3.31.0
Figma library GitLabReleases