# Customization

## Fields styling

To customize your secure fields with styles you have to add `css` object into your field initialization method to generate a standalone CSS.

What we support:

* Regular CSS properties
* Placeholders
* Generic Web Fonts and `@font-face` property
* Pseudo-classes (eg. `:hover`, `:focus`)
* Media queries (media query condition is calculated based on the iframe width, not on the parent window)

For your convenience, we've added classes that are mapping the current field state and are inherited from the main styles. You can style any of the following states by adding a selector to the `css` object:

* `& .invalid` - applied when the field has invalid value.
* `& .valid` - applied when the field has a valid value.
* `& .empty` - applied when the field doesn't have any value.
* `& .dirty` - applied once the user changed the value in the watched field.
* `& .touched` - indicates that the field has been touched, applied after the first blur event.

Example:

```javascript
form.field('#my-text-field-id', {
  type: 'text',
  name: 'my-text-field',
  placeholder: 'placeholder text',
  validations: ['required'],
  css: {
    'color': '#1b1d1f',
    'border': 'solid 1px #1b1d1f',
    'transition': 'border-color .15s ease-in-out',
    'border-radius': '5px',
    'padding': '0 10px',
    'box-sizing': 'border-box',
    '&:focus': {
      'border-color': '#11bef5',
    },
    '&.invalid.touched': {
      'color': 'red',
    },
    '&.valid': {
      'color': 'green',
    },
    '@media (min-width: 420px)': {
      'border-color': 'red',
    },
    '@font-face': {
      'font-family': 'PT Mono',
      'font-style': 'normal',
      'font-weight': '400',
      'font-display': 'swap',
      'src': 'local("PT Mono"), local("PTMono-Regular") url(https://fonts.gstatic.com/s/ptmono/v7/9oRONYoBnWILk-9AnCszM_HxEcn7Hg.woff2) format("woff2")',
      'unicode-range': 'U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116'
    },
    'font-family': '"PT Mono", monospace',
  }
});
```

## Web Fonts support

To perfectly match the font of your form with the font on your site you can choose one of the following options:

* Use Web safe CSS and HTML fonts (such as Arial, Verdana, Courier, etc).
* Set @font-face CSS property. The font can be either loaded from the remote server or a locally-installed font.

Examples:

{% tabs %}
{% tab title="Generic Web font" %}

```javascript
{
  'color': '#1b1d1f',
  'font-family': 'Arial, Helvetica, sans-serif',
}
```

{% endtab %}

{% tab title="@font-face" %}

```javascript
{
  '@font-face': {
    'font-family': 'PT Mono',
    'font-style': 'normal',
    'font-weight': '400',
    'font-display': 'swap',
    'src': 'local("PT Mono"), local("PTMono-Regular") url(https://fonts.gstatic.com/s/ptmono/v7/9oRONYoBnWILk-9AnCszM_HxEcn7Hg.woff2) format("woff2")',
    'unicode-range': 'U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116'
  },
  'color': '#1b1d1f',
  'font-family': '"PT Mono", monospace',
}
```

{% endtab %}

{% tab title="base64 encode @font-face" %}

```javascript
{
  '@font-face': {
    'font-family': 'CustomFont',
    'src': url(data:application/x-font-woff;charset=utf-8;base64,<base64 encoded string>) format('woff'),
  },
  'font-family': '"CustomFont", sans-serif',
}
    
```

{% endtab %}
{% endtabs %}

## Card brand identification

![](/files/vkgHxiBhSqcoHFstfHIR)

It will automatically determine the type of the credit card and show the desired icon. If you would like to show a card brand icon or an icon for CVV inside your field, just set `showCardIcon: true` inside the field initialization method.

Card Brand Icon:

```javascript
form.field('#cc-number', {
  type: 'card-number',
  name: 'cc-number',
  placeholder: 'Card number',
  validations: ['required', 'validCardNumber'],
  showCardIcon: true,
  }
});
```

Card CVC/CVV Icon:

```javascript
form.field('#cc-cvv', {
  type: 'card-security-code',
  name: 'cc-cvv',
  placeholder: 'CVV',
  validations: ['required', 'validCardSecurityCode'],
  showCardIcon: true,
});
```

> You're always able to get `cardType` value from the form [state](/vault/developer-tools/vgs-collect/js/integration.md#5-form-state).

We're supporting the following card brands:

| Card Brand         | State `cardType`     | Card Icon                                                                  | CVV Icon                                                          |
| ------------------ | -------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| Visa               | `visa`               | ![](https://js.verygoodvault.com/vgs-collect/icons/visa.svg)               | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Visa Electron      | `visaelectron`       | ![](https://js.verygoodvault.com/vgs-collect/icons/visa-electron.svg)      | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Maestro            | `maestro`            | ![](https://js.verygoodvault.com/vgs-collect/icons/maestro.svg)            | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Mastercard         | `mastercard`         | ![](https://js.verygoodvault.com/vgs-collect/icons/mastercard.svg)         | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Amex               | `amex`               | ![](https://js.verygoodvault.com/vgs-collect/icons/amex.svg)               | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-front.svg) |
| Discover           | `discover`           | ![](https://js.verygoodvault.com/vgs-collect/icons/discover.svg)           | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Dankort            | `dankort`            | ![](https://js.verygoodvault.com/vgs-collect/icons/dankort.svg)            | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Diners Club        | `dinersclub`         | ![](https://js.verygoodvault.com/vgs-collect/icons/diners-club.svg)        | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| JCB                | `jcb`                | ![](https://js.verygoodvault.com/vgs-collect/icons/jcb.svg)                | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| UnionPay           | `unionpay`           | ![](https://js.verygoodvault.com/vgs-collect/icons/unionpay.svg)           | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Forbrugsforeningen | `forbrugsforeningen` | ![](https://js.verygoodvault.com/vgs-collect/icons/forbrugsforeningen.svg) | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Elo                | `elo`                | ![](https://js.verygoodvault.com/vgs-collect/icons/elo.svg)                | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |
| Hipercard          | `hipercard`          | ![](https://js.verygoodvault.com/vgs-collect/icons/hipercard.svg)          | ![](https://js.verygoodvault.com/vgs-collect/icons/cvv-back.svg)  |

By default, the icon is a 31px-width image positioned on the right side of the input, but you can overwrite these styles as shown in the examples below:

{% tabs %}
{% tab title="Show Card Icon" %}

```javascript
form.field('#cc-number', {
  type: 'card-number',
  name: 'cc-number',
  placeholder: 'Card number',
  validations: ['required', 'validCardNumber'],
  showCardIcon: true,
  css: {
    color: '#1b1d1f',
    border: 'solid 1px #1b1d1f',
    transition: 'border-color .15s ease-in-out',
    borderRadius: '5px',
    padding: '0 10px',
    boxSizing: 'border-box',
    '&:focus': {
      borderColor: '#11bef5',
    },
  }
});c
```

{% endtab %}

{% tab title="Change Icon Position" %}

```javascript
form.field('#cc-number', {
  type: 'card-number',
  name: 'cc-number',
  placeholder: 'Card number',
  validations: ['required', 'validCardNumber'],
  showCardIcon: {
    left: '5px',
  },
  css: {
    boxSizing: 'border-box',
    paddingLeft: '45px',
    paddingRight: '0',
  }
});
```

{% endtab %}

{% tab title="Change Icon Size" %}

```javascript
form.field('#cc-number', {
  type: 'card-number',
  name: 'cc-number',
  placeholder: 'Card number',
  validations: ['required', 'validCardNumber'],
  showCardIcon: {
    width: '37px',
    height: '25px',
  },
});
```

{% endtab %}
{% endtabs %}

## Add custom card brands

To extend the list of supported card brands, you can specify `addCardBrand` field property. In the scope of this feature, it's also possible to redefine existing card brand patterns. It takes an array of objects with required configuration parameters, such as:

| Param          | Description                                                                                                             | Default value  |
| -------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------- |
| type           | *String*. `cardType` will be shown in the form [state](/vault/developer-tools/vgs-collect/js/integration.md#form-state) | required       |
| pattern        | *RegExp*. Custom card validation pattern                                                                                | required       |
| format         | *RegExp*. Mask for the input (e.g. split value with spaces)                                                             | `/(\d{1,4})/g` |
| length         | *Array*. Card number length                                                                                             | `[16]`         |
| cvcLength      | *Array*. Available CVC number length                                                                                    | `[3,4]`        |
| luhn           | *Boolean*. Specify whether card should pass luhn check or not                                                           | `true`         |
| useExtendedBin | *Boolean*. Return 8 digit BIN in the form state.                                                                        | `false`        |

{% tabs %}
{% tab title="Add new card brand" %}

```javascript
form.field('#cc-number', {
  type: 'card-number',
  name: 'cc-number',
  placeholder: 'Card number',
  validations: ['required', 'validCardNumber'],
  showCardIcon: true,
  addCardBrands: [{
    type: 'mycard',
    pattern: /^221/,
    format: /(\\d{1,4})/g,
    length: [16, 19],
    cvcLength: [3, 4],
    luhn: false,
  },],
});
```

{% endtab %}

{% tab title="Change existing card brand config" %}

```javascript
form.field('#cc-number', {
    type: 'card-number',
    name: 'cc-number',
    placeholder: 'Card number',
    validations: ['required', 'validCardNumber'],
    showCardIcon: true,
    addCardBrands: [{
      type: 'visa',
      pattern: /^411/, // now visa card will be valid only if it starts from 411
    },],
  });
```

{% endtab %}

{% tab title="Default Cards Configuration" %}

```javascript
   {
       type: 'visa',
       pattern: /^4/,
       format: /(\\d{1,4})/g,
       length: [13, 16],
       cvcLength: [3],
       luhn: true
    },
    {
       type: 'visaelectron',
       pattern: /^4(026|17500|405|508|844|91[37])/,
       format: /(\\d{1,4})/g,
       length: [16],
       cvcLength: [3],
       luhn: true
    },
    {
       type: 'mastercard',
       pattern: /^(5[1-5][0-9]{4}|677189)|^(222[1-9]|2[3-6]\\d{2}|27[0-1]\\d|2720)([0-9]{2})/,
       format: /(\\d{1,4})/g,
       length: [16],
       cvcLength: [3],
       luhn: true
    },
    {
       type: 'amex',
       pattern: /^3[47]/,
       format: /(\\d{1,4})(\\d{1,6})?(\\d{1,5})?/,
       length: [15],
       cvcLength: [4],
       luhn: true
     },
     {
       type: 'hipercard',
       pattern: /^(384100|384140|384160|606282|637095|637568|60(?!11))/,
       format: /(\\d{1,4})/g,
       length: [14, 15, 16, 17, 18, 19],
       cvcLength: [3],
       luhn: true
     },
     {
       type: 'maestro',
       pattern: /^(5018|5020|5038|6304|6390[0-9]{2}|67[0-9]{4})/,
       format: /(\\d{1,4})/g,
       length: [12, 13, 14, 15, 16, 17, 18, 19],
       cvcLength: [3],
       luhn: true
      },
      {
        type: 'dankort',
        pattern: /^5019/,
        format: /(\\d{1,4})/g,
        length: [16],
        cvcLength: [3],
        luhn: true
      },
      {
        type: 'discover',
        pattern: /^(6011|65|64[4-9]|622)/,
        format: /(\\d{1,4})/g,
        length: [16],
        cvcLength: [3],
        luhn: true
      },
      {
        type: 'unionpay',
        pattern: /^62/,
        format: /(\\d{1,4})/g,
        length: [16, 17, 18, 19],
        cvcLength: [3],
        luhn: false
      },
      {
        type: 'jcb',
        pattern: /^35/,
        format: /(\\d{1,4})/g,
        length: [16],
        cvcLength: [3],
        luhn: true
      },
      {
        type: 'dinersclub',
        pattern: /^3(?:[689]|(?:0[059]+))/,
        format: /(\\d{1,4})(\\d{1,6})?(\\d{1,6})?/,
        length: [14, 16],
        cvcLength: [3],
        luhn: true
      },
      {
        type: 'elo',
        pattern: /^(4011(78|79)|43(1274|8935)|45(1416|7393|763(1|2))|50(4175|6699|67[0-7][0-9]|9000)|627780|63(6297|6368)|650(03([^4])|04([0-9])|05(0|1)|4(0[5-9]|3[0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8])|9([2-6][0-9]|7[0-8])|541|700|720|901)|651652|655000|655021)/,
        format: /(\\d{1,4})/g,
        length: [16],
        cvcLength: [3],
        luhn: true
      },
      {
        type: 'forbrugsforeningen',
        pattern: /^600/,
        format: /(\\d{1,4})/g,
        length: [16],
        cvcLength: [3],
        luhn: true
      },  
```

{% endtab %}
{% endtabs %}

## Override default icons

You can customize VGS Collect.js icons, but due to security reasons, regular HTTP(s) URLs are not allowed. You can pass a [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) with an image encoded.

**Example:**

```javascript

const cvvIcon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' enable-background='new 0 0 24 24' height='24px' viewBox='0 0 24 24' width='24px' fill='%233BBF45'%3E%3Cg%3E%3Cpath d='M0,0h24v24H0V0z' fill='none'/%3E%3C/g%3E%3Cg%3E%3Cg%3E%3Cpath d='M20,4H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M7.64,15H6.49v-4.5l-0.9,0.66 l-0.58-0.89L6.77,9h0.87V15z M13.5,15H9.61v-1.02c1.07-1.07,1.77-1.77,2.13-2.15c0.4-0.42,0.54-0.69,0.54-1.06 c0-0.4-0.31-0.72-0.81-0.72c-0.52,0-0.8,0.39-0.9,0.72l-1.01-0.42c0.01-0.02,0.18-0.76,1-1.15c0.69-0.33,1.48-0.2,1.95,0.03 c0.86,0.44,0.91,1.24,0.91,1.48c0,0.64-0.31,1.26-0.92,1.86c-0.25,0.25-0.72,0.71-1.4,1.39l0.03,0.05h2.37V15z M18.75,14.15 C18.67,14.28,18.19,15,16.99,15c-0.04,0-1.6,0.08-2.05-1.51l1.03-0.41c0.03,0.1,0.19,0.86,1.02,0.86c0.41,0,0.89-0.28,0.89-0.77 c0-0.55-0.48-0.79-1.04-0.79h-0.5v-1h0.46c0.33,0,0.88-0.14,0.88-0.72c0-0.39-0.31-0.65-0.75-0.65c-0.5,0-0.74,0.32-0.85,0.64 l-0.99-0.41C15.2,9.9,15.68,9,16.94,9c1.09,0,1.54,0.64,1.62,0.75c0.33,0.5,0.28,1.16,0.02,1.57c-0.15,0.22-0.32,0.38-0.52,0.48 v0.07c0.28,0.11,0.51,0.28,0.68,0.52C19.11,12.91,19.07,13.66,18.75,14.15z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E";
const cardIcon = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='24px' viewBox='0 0 24 24' width='24px' fill='%233BBF45'%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3Cpath d='M21 18v1c0 1.1-.9 2-2 2H5c-1.11 0-2-.9-2-2V5c0-1.1.89-2 2-2h14c1.1 0 2 .9 2 2v1h-9c-1.11 0-2 .9-2 2v8c0 1.1.89 2 2 2h9zm-9-2h10V8H12v8zm4-2.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z'/%3E%3C/svg%3E";

const css = {
  fontSize: 22,
  fontFamily:
    '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif',
};

form.field("#cc-number", {
  type: 'card-number',
  name: 'cc-number',
  placeholder: '4111 1111 1111 1111',
  showCardIcon: true,
  icons: {
    cardPlaceholder: cardIcon,
  },
  css,
});

form.field("#cc-cvv", {
  type: 'card-security-code',
  name: 'cc-cvv',
  placeholder: '111',
  showCardIcon: true,
  icons: {
    cvvFront: cvvIcon,
    cvvBack: cvvIcon,
  },
  css,
});
  
```

### Change text allignment to Right-To-Left in inputs

You can customize VGS Collect.js inputs to receive text in Right-To-Left style with these specified CSS styles.

**Example:**

```javascript
const css = {
  direction: "ltr",
  unicodeBidi: "embed",
  textAlign: "right",
};
form.field("#cc-number", {
  type: 'card-number',
  name: 'cc-number',
  placeholder: '4111 1111 1111 1111',
  showCardIcon: true,
  css,
});
form.field("#cc-cvv", {
  type: 'card-security-code',
  name: 'cc-cvv',
  placeholder: '111',
  css,
});
form.field("#cc-expiration-date", {
  type: 'card-expiration-date',
  name: 'cc-expiration-date',
  placeholder: '111',
  css,
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.verygoodsecurity.com/vault/developer-tools/vgs-collect/js/customization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
