How the SDK's state-and-category styling model works, including precedence rules and common pitfalls.
Checkout Components uses a structured styling system — not inline CSS — built around states (default, hover, focus, error) and categories (card, input, button). Understanding the model makes the difference between a theme that works predictably and one that breaks on interaction. This page explains how the system works, what controls precedence, and where to find the full property catalog for each component.
The SDK defaults card.backgroundColor to #ffffff on hover and active states. If you only set state.default.card.backgroundColor to a dark value, the card will flash white when the user interacts with it. See the full example below.
How it works
Styles are organized by state and category. A state describes when the styles apply (default, hover, focus, error, etc.). A category targets a specific part of the component (card, input, button, etc.).
sdk.components.create('fs-card', {
style: {
state: {
// ↑ state
default: {
card: {
// ↑ category
backgroundColor: '#ffffff', // ← property
borderRadius: '12px',
},
input: {
borderColor: '#e5e7eb',
height: '48px',
},
},
focus: {
input: {
borderColor: '#2563eb', // overrides default only on focus
},
},
},
},
});Precedence — most specific wins:
- State-specific category styles — e.g.
state.focus.input.borderColor - Default-state category styles — e.g.
state.default.input.borderColor globalStylesonFastSpring.init()— base defaults across all components
Anything not set at any level falls back to the SDK's built-in defaults, documented on each component's reference page.
Global styles
Use globalStyles on FastSpring.init() to set a consistent base across every mounted component without repeating yourself in each component's style object.
const sdk = FastSpring.init({
checkoutUrl: '...',
globalStyles: {
fontFamily: 'Inter, sans-serif',
color: '#0f172a',
fontSize: '14px',
},
});| Property | Type | Description |
|---|---|---|
fontFamily | string | Base font family for all components |
color | string | Base text color for all components |
fontSize | string | Base font size for all components |
Component-level style values always override globalStyles.
Available states per component
| State | fs-card | fs-pay-button | fs-disclosures |
|---|---|---|---|
default | ✅ | ✅ | ✅ |
hover | ✅ | ✅ | ✅ |
focus | ✅ | ✅ | — |
active | ✅ | ✅ | — |
error | ✅ | ✅ | — |
disabled | — | ✅ | — |
valid | — | ✅ | — |
States that accept overrides but apply no SDK-default visual change (e.g.
hoveronfs-card) still work — you need to set the values explicitly for any differentiation to appear.
A common pitfall: dark backgrounds and state flicker
The SDK ships with #ffffff as the default card.backgroundColor for the hover and active states on fs-card. If you only override state.default.card.backgroundColor to a dark value, the card will flash white when the user hovers or clicks it.
Always pair a non-default base background with matching overrides on every interactive state:
state: {
default: { card: { backgroundColor: '#1e293b', borderColor: '#334155' } },
hover: { card: { backgroundColor: '#1e293b', borderColor: '#334155' } },
focus: { card: { backgroundColor: '#1e293b', borderColor: '#334155' } },
active: { card: { backgroundColor: '#1e293b', borderColor: '#475569' } },
}Style properties by component
Each component exposes different style categories and properties. See the component reference pages for the complete catalog:
Ready-to-use templates
Three drop-in styling templates — Polished Light, Dark, and Minimal — are available in the Integration Guide. Each styles all three components cohesively and is a working starting point you can paste in and adjust.
For the exhaustive property reference across all components and states, see the Style Properties Reference on GitHub.
