Button
For click events
Introduction
Buttons trigger actions and guide users through an application. Bifrost provides three variants with five states to express visual hierarchy and intent — with built-in theme and dark mode support.
Hierarchy
Three variants establish a visual hierarchy:
- Filled: Primary button with solid background color with contrasting text color. Use it for primary actions or call-to-actions, as the filled button variant stand out and signals importance.
- Basic: Secondary button with no fill, just a border and text. Use it for secondary actions where you want to offer an alternative without competing with the primary button.
- Flat: Tertiary button with no fill or border, only a label. The least prominent option — ideal for supplementary actions that should stay in the background.
Interactive demo
States
- Default: Uses theme colors to signal that the button is enabled and ready to interact with.
- Alert: For potentially destructive or irreversible actions like deleting an item or revoking access.
- Inactive: Use in flows where the user must do something before the action becomes available. Its muted, gray appearance signals that the button isn't ready yet. Unlike disabled, inactive buttons can still be interacted with and read by screen readers. Always match the inactive variant to the one it will become when enabled (e.g. inactive filled → active filled).
- Neutral: An alternative to themed buttons for color-heavy UIs. Neutral buttons help reduce visual noise and make the interface feel more balanced. Use neutral filled when a button is still important but shouldn't act as a replacement for the primary filled theme button — for example a secondary action further down the page. Use neutral basic or flat for less prominent actions where you want even less visual weight than their themed counterparts.
- Inverted: For buttons placed on high-contrast backgrounds like bfc-neutral or bfc-theme, where themed buttons wouldn't have enough contrast.
Loading state
When a button triggers an async action, set it to inactive state to block duplicate submissions. Keep the label unchanged — only replace the icon with a spinner at the same position to avoid layout jumps. Only do this if you expect the action to take more than 2–3 seconds.
Try it using the Loading toggle in the demo above. See Loading state for more details on how to handle loading states in your UI.
Best practices
Alert
Match the variant to how serious the consequence is — flat for low risk, basic for medium, filled for actions that can't be undone.
Always make it obvious what a destructive action does. If you're using an icon-only button, wrap it in a tooltip so users know exactly what they're triggering.
A minus, ban, or archive icon could mean a lot of things — users shouldn't have to guess whether they're about to delete something.
Mixing themes
Avoid mixing button themes unless there's a clear reason — it can easily look like a mistake.
Using different themes is fine when each button links to a different product — the color helps users recognize where they're headed.
Mixing themes for buttons in the same flow looks unintentional and confuses users about which action belongs to what.
Neutral
Neutral buttons tone down the visual weight when your UI already has a lot of color going on.
Two equally valid options? The neutral filled button signals "alternative" without competing with the primary action for attention.
Neutral filled sits outside the normal hierarchy, so combining it with themed flat or basic buttons sends mixed signals about what's most important.
Related components
Buttons can be used with various components: