Skip to content

Styling the iFrame

The card and bank iFrames are styled with a customStyle object that you pass in the component options. You cannot reach inside the iFrame with your own CSS — this object is the whole interface.

The shape of it

customStyle has a styles key. Inside it, base sets the style for every input:

var customStyle = {
  styles: {
    base: {
      color: 'blue'
    }
  }
};

To style the field labels, use labels as a top-level key with base nested inside it:

var customStyle = {
  styles: {
    base: {
      color: 'blue'
    },
    labels: {
      base: {
        'font-weight': 'bold'
      }
    }
  }
};

Styling individual elements

Name an element as a key alongside base, with its own nested base and labels:

Class name Notes
cc-number The card number input.
cvv-number The CVV input.
cvv-icon Only base.display is honoured — use it to hide the icon. Nothing else applies.
expiration-month There is one label for the whole expiry date. If you want to style that label, nest it here.
expiration-year Do not style this. Style expiration-month instead.
errors Only color is accepted.

Element styles override base where the two conflict.

Supported CSS properties

Only these are passed through. Anything else is ignored.

appearance, border, border-left, border-right, border-top, border-bottom, border-color, border-radius, box-shadow, color, display (cvv-icon only), font-size, font-weight, font-family, font-smooth, font-style, font-variant, letter-spacing, line-height, margin, padding, text-decoration, text-shadow, text-transform, transition, width

And these pseudo-classes: :hover, :focus, ::placeholder, ::selection

Warning

Pass margin, box-shadow and width in pixels. Percentages and em values cause the inputs to misalign with the iFrame, because the iFrame sizes itself from these values and cannot resolve units relative to your page.

A worked example

Global styling, one element override, and the component options together:

var customStyle = {
  styles: {
    base: {
      color: 'blue',
      'border-color': 'blue',
      'border-radius': '4px',
      height: '56px',
      'font-size': '16px',
      '::placeholder': {
        color: '#888'
      }
    },
    'cvv-icon': {
      base: {
        display: 'none'
      }
    },
    errors: {
      base: {
        color: '#b3261e'
      }
    }
  }
};

var options = {
  customStyle: customStyle,
  showPlaceholders: false,
  showErrorMessages: true
};

Then pass options when you create the component — see capture a card.

The other two options

Option Effect
showPlaceholders Whether the inputs show placeholder text.
showErrorMessages Whether validation messages appear inside the iFrame. Turn this off only if you are rendering the errors from the token callback yourself — otherwise the payer gets no feedback at all.

Things to get right

  • Set a font size of at least 16px. Mobile Safari zooms the page when focusing an input smaller than that, which on an iFrame looks broken.
  • Style the focus state. The payer is typing a card number; they need to see which field they are in. :focus is supported — use it.
  • Match your own inputs. The iFrame sits among your form fields. If it does not match them, it reads as untrustworthy, which is the opposite of what you want on a payment form.
  • Check it in dark mode if your page has one. The iFrame will not follow your theme on its own.