Skip to main content

Theming

Odus Elements uses CSS custom properties for styling, giving you fine-grained control over every element's visual appearance. Each element renders inside its own Shadow DOM and inherits theme variables from CSS custom properties set on its host element.

You can apply a theme in two ways:

  • GloballyapplyTheme() sets variables on all instantiated elements at once.
  • Per-elementsetTheme() overrides the global theme for a single element.

Theme Variables

The following CSS custom properties are available, shown with their default values:

Font

VariableDefaultDescription
--odus-font-familysystem-ui, sans-serifBase font family for all elements
--odus-font-size16pxBase font size

When you set --odus-font-family via applyTheme(), the corresponding Google Font is automatically loaded by injecting a <link> stylesheet into the document head. The font is removed when you call resetTheme() with --odus-font-family or when the checkout instance is destroyed.

Supported font families:

  • Roboto
  • Open Sans
  • Lato
  • Montserrat
  • Poppins
  • Inter
  • Noto Sans
  • Source Sans Pro
  • Raleway
  • Ubuntu
  • Work Sans
  • Nunito
  • Quicksand
  • Rubik
  • DM Sans

Colors

VariableDefaultDescription
--odus-color-error#dc2727Error state color
--odus-color-text#1a1a1aDefault text color
--odus-color-background#ffffffBackground color

Borders

VariableDefaultDescription
--odus-border-color#e0e0e0Default border color for inputs
--odus-border-radius6pxBorder radius for inputs and buttons

Spacing

VariableDefaultDescription
--odus-spacing-sm8pxSmall spacing unit
--odus-spacing-md16pxMedium spacing unit
--odus-spacing-lg24pxLarge spacing unit

Inputs

VariableDefaultDescription
--odus-input-height44pxInput field height
--odus-input-padding8px 12pxInput field padding
--odus-input-font-sizevar(--odus-font-size)Input text font size
--odus-input-font-weight400Input text font weight
--odus-input-letter-spacing0.02emInput text letter spacing
--odus-input-line-height1.5Input text line height
--odus-input-placeholder-color#717173Placeholder text color
--odus-input-placeholder-opacity0.3Placeholder text opacity
--odus-input-focus-shadowblue glow ringBox shadow applied on input focus

Labels

VariableDefaultDescription
--odus-label-font-size14pxLabel font size
--odus-label-font-weight500Label font weight
--odus-label-colorinheritedLabel text color
--odus-label-letter-spacinginheritedLabel letter spacing
--odus-label-line-height1.4Label line height
--odus-label-margin-bottom6pxSpace between label and input

Validation messages

VariableDefaultDescription
--odus-helper-text-line-height14pxHeight of one validation message line
--odus-helper-text-space4pxSpace reserved below a field for it

A validation message is drawn below its field but outside the layout, so an element never changes height when one appears or clears and nothing on your page moves. Each field reserves only --odus-helper-text-space — a thin strip that keeps the message off whatever follows — and the message itself overhangs into the gap you already have between fields.

That overhang paints over what sits beneath it, on the form's own background colour and without intercepting clicks, so allow roughly 16px below each element. Every message we ship fits one line at usual widths, but a narrow element can still wrap one onto a second line. Errors and hints (such as the email "did you mean" suggestion) share one row per field, so a field looks the same height whichever it shows.

Card & Button

VariableDefaultDescription
--odus-card-gap12pxGap between card sub-fields (number, expiry, CVV)
--odus-button-height48pxExpress button height
--odus-button-border-radiusvar(--odus-border-radius)Express button border radius

Applying a Theme

Global Theme

Use applyTheme() to set theme variables on all instantiated elements at once:

checkout.applyTheme({
'--odus-color-text': '#f8fafc',
'--odus-color-background': '#1e293b',
'--odus-border-color': '#334155',
'--odus-border-radius': '8px',
'--odus-font-family': 'Inter',
});

To remove specific theme overrides and revert to defaults:

checkout.resetTheme({
'--odus-color-background': '',
});

Per-Element Theme

Override theme variables on a single element using setTheme() on the element instance:

checkout.elements.card.setTheme({
'--odus-border-color': '#6366f1',
'--odus-input-height': '52px',
});

// Reset to defaults
checkout.elements.card.resetTheme({
'--odus-border-color': '',
'--odus-input-height': '',
});

Example: Dark Theme

const darkTheme = {
'--odus-color-error': '#f87171',
'--odus-color-text': '#f1f5f9',
'--odus-color-background': '#0f172a',
'--odus-border-color': '#334155',
'--odus-border-radius': '10px',
'--odus-input-placeholder-color': '#94a3b8',
'--odus-input-placeholder-opacity': '0.6',
'--odus-input-focus-shadow': '0 0 0 2px rgba(129, 140, 248, 0.4)',
'--odus-label-color': '#cbd5e1',
};

checkout.applyTheme(darkTheme);
tip

Because Elements uses CSS custom properties, you can also set these variables in your own CSS stylesheets or via inline styles on the container elements. The Shadow DOM will inherit the values through the host element.

tip

Want to experiment with themes visually? Try the interactive Elements Builder to preview theme changes in real time and export the configuration.