---
title: "Options and styling"
description: "Every OrderCard.init() option, the theme variables, and the CSS you can apply inside the form."
image: "https://docs.ordercard.io/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ordercard.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Options and styling

`OrderCard.init(publishableKey, options)` creates the form and returns an object you call methods on. Every option is optional except the key.

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `container` | `#ordercard-fields` | A selector or element to put the form in. |
| `layout` | `separate` | `separate` gives every field its own box and label. `inline` joins related fields into one box under a group label, with the number, expiry and security code on one line when there is room. |
| `fields` | `{}` | Extra fields: `name`, and either `postal_code` or `billing_address`. For example `{ name: true, billing_address: true }`. |
| `defaultValues` | | Start shown fields filled in: `{ billing: { name: "Jane Doe", country: "CA" } }`. Same keys as below. |
| `showCardBrand` | `true` | Show card brand marks in the number field: the accepted brands, then the detected one. |
| `requireCvv` | `true` | Set `false` to allow cards without a security code. |
| `showErrors` | `true` | Show error messages in the form. Set `false` to render them yourself from the `errors` event. |
| `hideLabels` | `false` | Hide the field labels. |
| `numberFormat` | `pretty` | `pretty` (groups of four), `plain` (digits only) or `masked` (hidden like a password). |
| `theme` | | Theme variables, below. |
| `styles` | | CSS for parts of the form, below. |
| `placeholders` | | Placeholder text per field: `{ number: "Card number" }`. |
| `labels` | | Label text per field. |
| `font` | | A font to load: `{ family: "Inter", url: "https://fonts.googleapis.com/css2?family=Inter" }`. |
| `autoResize` | `true` | Grow and shrink the iframe to fit the form. |
| `height` | `180` | Starting iframe height in pixels. |
| `title` | `Secure card payment form` | The iframe's accessible title. |

Fields are named `number`, `expiry`, `cvv`, `name`, `postal_code`, and for the billing address `country`, `address_line1`, `address_line2`, `city` and `state`.

Fields you turn on are required, except `address_line2`, and `state` outside the United States. The billing address includes the postal code, so `billing_address` replaces `postal_code` when you set both. The country list comes from the customer's browser and starts at the region in their language settings, or at `defaultValues.billing.country`.

## Details from your own form

If your checkout already asks for the name or address, leave those fields off and pass the details when you tokenize. They take the same `billing` object as [creating a payment method](/api/payment-methods) from your server, plus `name` for a full name, which is split into `first_name` and `last_name`:

```js
const { token } = await card.tokenize({
  billing: {
    name: "Jane Doe",
    email: "jane@example.com",
    address_line1: "123 Example Street",
    city: "Chicago",
    state: "IL",
    postal_code: "60601",
    country: "US",
  },
  metadata: { order_id: "1042" },
});
```

You can mix the two: show the postal code in the form and pass the rest of the address. Anything the customer typed in a field the form shows wins over the same detail you pass. An unknown key (`zip` instead of `postal_code`, say) rejects `tokenize()` with `errors.configuration` and logs a `consoleError`, so a typo can't silently drop data. `metadata` follows the same [rules as the API](/api/conventions#metadata). The customer is never one of these details: link cards to customers from your server.

## Theme variables

Pass them in `theme` or later with `setTheme()`. Values are plain CSS values.

| Variable | Example |
| --- | --- |
| `fontFamily`, `fontSize`, `fontWeight`, `letterSpacing` | `"Inter, sans-serif"`, `"16px"` |
| `color`, `placeholderColor`, `backgroundColor` | `"#111827"` |
| `labelColor`, `labelSize`, `labelWeight` | `"#374151"` |
| `borderColor`, `borderWidth`, `borderRadius` | `"#d1d5db"`, `"1px"`, `"8px"` |
| `focusBorderColor`, `focusShadow` | `"#2563eb"`, `"0 0 0 3px rgb(37 99 235 / .2)"` |
| `errorColor` | `"#dc2626"` |
| `padding`, `height`, `gap` | `"10px 12px"`, `"44px"`, `"12px"` |

```js
card.setTheme({ borderRadius: "999px", focusBorderColor: "#16a34a" });
```

## CSS for parts of the form

For anything the theme does not cover, pass CSS declarations for a part of the form in `styles`, or call `setStyle(target, css)`:

```js
card.setStyle("input", "font-size: 15px; letter-spacing: .02em; box-shadow: none");
card.setStyle("input:focus", "border-color: #16a34a");
card.setStyle("label", "text-transform: uppercase; font-size: 11px");
```

Targets: `form`, `input`, `input:focus`, `input:invalid`, `placeholder`, `label`, `error`, `alert` (problems that belong to no field), `group` (the shared box in the `inline` layout), `brand`, and the fields by name (`number`, `expiry`, `cvv`, `name`, `postal_code`, `country`, `address_line1`, `address_line2`, `city`, `state`).

Only these properties are applied: colours, `font-*`, `letter-spacing`, `line-height`, `text-align`, `text-transform`, `text-decoration`, `border*`, `padding*`, `margin`, `margin-top`, `margin-bottom`, `height`, `min-height`, `outline`, `box-shadow`, `opacity`, `transition`, `gap`, `appearance`, `caret-color` and `-webkit-font-smoothing`. Values with `url(`, `expression(`, `@import`, braces or semicolons are dropped. The form's security policy also blocks inline styles and scripts, so nothing else can be injected into it.

## Fonts

Fonts load from Google Fonts only:

```js
card.setFont({ family: "Inter", url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;600" });
```

Source: https://docs.ordercard.io/hosted-fields/options/index.mdx
