Estilizando elementos

Estilize os campos seguros do Tokeflow Bridge SDK com a API ElementStyle e reflita o estado ao vivo do elemento no seu próprio contêiner usando CSS.

Os campos seguros do Tokeflow são executados dentro de iframes isolados e cross-origin; os dados do cartão são criptografados no navegador e nunca chegam aos seus servidores. Como os inputs vivem em outra origem, você não consegue acessá-los por dentro com o CSS da sua página — por isso o Bridge SDK oferece uma API estruturada ElementStyle para estilizar o texto dentro do iframe, e um evento change que você usa para estilizar o contêiner ao redor do iframe.

Juntas, essas duas camadas permitem que os campos seguros se integrem perfeitamente à sua marca, mantendo os dados do portador do cartão totalmente isolados.

A estilização é puramente apresentacional. Ela nunca altera como os dados são coletados, criptografados ou tokenizados — veja Tokenização para o fluxo de dados.

As duas camadas de estilização

Existem duas superfícies distintas, e elas são estilizadas de duas formas diferentes.

CamadaO que ela estilizaComo você estiliza
Dentro do iframeO texto do input, o placeholder e o cursor renderizados pelo campo seguroObjeto ElementStyle passado como style
Ao redor do iframeBordas, padding, fundo, anel de foco, estados de validaçãoSeu próprio CSS, orientado pelo evento change

A API ElementStyle

Passe um objeto style ao criar um elemento. Ele mapeia regras de estilo para o input renderizado dentro do iframe.

const style = {
  base: {
    color: '#333333',
    fontSize: '16px',
    fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
    fontWeight: '400',
    lineHeight: '24px',
    '::placeholder': { color: '#aaaaaa', fontStyle: 'italic' },
    ':focus': { color: '#000000' },
  },
  complete: { color: '#28a745' }, // input is complete and valid
  invalid: { color: '#dc3545' },  // input is invalid
  empty: { color: '#6c757d' },    // input is empty
};

const cardElement = tokeflow.createCardElement({ style });

Estilos base

O objeto base contém a aparência padrão, aplicada em todos os estados a menos que seja sobrescrita por um bloco específico de estado. Estas são as propriedades tipográficas centrais suportadas.

PropriedadeTypeDescrição
colorstringCor do texto do valor do input (qualquer cor CSS).
fontSizestringTamanho da fonte do texto do input, por exemplo "16px".
fontFamilystringPilha de fontes para o texto do input. Veja Carregando fontes personalizadas.
fontWeightstringPeso da fonte, por exemplo "400" ou "600".
lineHeightstringAltura da linha do texto do input, por exemplo "24px".

Combine fontSize, fontFamily e lineHeight com os inputs do formulário ao redor para que o campo seguro seja visualmente indistinguível dos seus campos nativos.

Pseudo-seletores

Dentro de base, dois pseudo-seletores permitem que você mire em subestados do input.

SeletorAlvo
::placeholderO texto do placeholder exibido enquanto o campo está vazio.
:focusO input enquanto está em foco.

Cada um aceita as mesmas propriedades tipográficas que base:

const style = {
  base: {
    color: '#1a1a1a',
    fontSize: '16px',
    '::placeholder': {
      color: '#9aa0a6',
      fontStyle: 'italic',
    },
    ':focus': {
      color: '#000000',
    },
  },
};

Estilos de estado

Além de base, você pode fornecer blocos de estado de nível superior que sobrescrevem a cor base (e outras propriedades) conforme o input do portador do cartão muda. O SDK os aplica automaticamente com base no estado ao vivo do elemento.

EstadoAplicado quandoUso típico
emptyO campo ainda não tem valorSuavizar a cor do cursor/texto antes do input
completeO valor está completo e válidoConfirmar sucesso com um tom verde
invalidO valor atual falha na validaçãoAlertar com um tom vermelho
const style = {
  base: {
    color: '#333333',
    fontSize: '16px',
    lineHeight: '24px',
  },
  empty: { color: '#6c757d' },
  complete: { color: '#28a745' },
  invalid: { color: '#dc3545' },
};

Os estilos de estado afetam apenas propriedades que você pode definir no texto do input (como color). Para reestilizar o frame — bordas, fundo, sombras — oriente seu contêiner com o evento change, descrito em Estilização do contêiner.

Carregando fontes personalizadas

Se o seu fontFamily referenciar uma web font que não seja uma fonte de sistema, declare-a por meio do array fonts para que o iframe possa carregá-la. Use a mesma opção em elementOptions (aplicada a todos os elementos) ou por elemento.

const tokeflow = new TokeflowBridge({
  publicKey: 'pk_live_mer_xxxxxxxx',
  elementOptions: {
    fonts: ['https://fonts.example.com/inter.css'],
    style: {
      base: {
        fontFamily: '"Inter", sans-serif',
        fontSize: '16px',
      },
    },
  },
});

Chaves públicas (pk_live_…) podem ser incluídas com segurança no código do navegador. Nunca coloque uma chave secreta (sk_live_…) em código do lado do cliente — veja Autenticação.

Estilização do contêiner

O iframe fica dentro de um elemento contêiner que você controla. Estilize esse contêiner com CSS comum para lidar com tudo o que o iframe não pode: bordas, padding, fundo, anéis de foco e estados de validação.

Duas técnicas funcionam em conjunto:

  1. :focus-within — uma pseudo-classe CSS nativa que casa com o seu contêiner sempre que o foco estiver dentro dele (inclusive dentro do iframe). Use-a para o anel de foco sem precisar de JavaScript.
  2. Classes de estado a partir do evento change — alterne suas próprias classes (por exemplo, invalid, complete) no contêiner em resposta ao estado ao vivo do elemento.

CSS

.card-element-container {
  border: 1px solid #dddddd;
  border-radius: 8px;
  padding: 12px;
  background: #fafafa;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

/* Focus ring — pure CSS, fires when focus is inside the iframe */
.card-element-container:focus-within {
  border-color: #0066ff;
  box-shadow: 0 0 0 3px rgba(0, 102, 255, 0.15);
}

/* Validation states — toggled from the change event */
.card-element-container.invalid {
  border-color: #dc3545;
}
.card-element-container.complete {
  border-color: #28a745;
}

JavaScript

Monte o elemento no contêiner e, em seguida, reflita seu estado no contêiner a partir do evento change.

const cardElement = tokeflow.createCardElement({ style });
cardElement.mount('.card-element-container');

const container = document.querySelector('.card-element-container');

cardElement.on('change', (event) => {
  // event.error is singular; event.empty / event.complete are booleans
  container.classList.toggle('invalid', !!event.error && !event.empty);
  container.classList.toggle('complete', event.complete);
});

O payload do evento change expõe apenas estado e metadados não sensíveis — nunca os dados brutos do cartão:

interface ElementChangeEvent {
  elementType: ElementType;
  empty: boolean;
  complete: boolean;
  error?: ElementError;   // singular — there is no `errors` array
  value?: {               // non-sensitive metadata only
    type?: string;
    brand?: string;       // e.g. 'visa', 'mastercard'
    bin?: string;
    last4?: string;
  };
}

Você também pode ler o mesmo estado de forma síncrona a qualquer momento com element.getState(), que retorna { empty, focused, valid, invalid, complete, error? }. O evento change é ideal para UI ao vivo; getState() é ideal para verificações pontuais (por exemplo, antes de tokenizar).

Juntando tudo

Um campo de cartão mínimo e totalmente estilizado:

<div class="card-element-container"></div>
const tokeflow = new TokeflowBridge({ publicKey: 'pk_live_mer_xxxxxxxx' });
await tokeflow.init();

const cardElement = tokeflow.createCardElement({
  style: {
    base: {
      color: '#1a1a1a',
      fontSize: '16px',
      fontFamily: '"Inter", sans-serif',
      lineHeight: '24px',
      '::placeholder': { color: '#9aa0a6' },
    },
    complete: { color: '#28a745' },
    invalid: { color: '#dc3545' },
  },
  placeholder: {
    cardNumber: '1234 5678 9012 3456',
    cardExpirationDate: 'MM/YY',
    cardSecurityCode: 'CVC',
  },
});

cardElement.mount('.card-element-container');

const container = document.querySelector('.card-element-container');
cardElement.on('change', (event) => {
  container.classList.toggle('invalid', !!event.error && !event.empty);
  container.classList.toggle('complete', event.complete);
});

Objeto theme avançado

O ElementStyle cobre os casos comuns. Para um controle mais granular, você pode passar um objeto theme de nível mais baixo, com um mapa styles indexado por seletores internos. Isso é uma saída de emergência para layouts avançados e não é necessário para a maioria das integrações.

const cardElement = tokeflow.createCardElement({
  theme: {
    styles: {
      '.field input': { fontSize: 16, color: '#333333' },
    },
  },
});

Os seletores de theme miram na estrutura interna do elemento e são menos estáveis entre versões do SDK do que o ElementStyle. Prefira o ElementStyle para portabilidade, e recorra ao theme apenas quando precisar de uma regra que o ElementStyle não exponha.

Próximos passos

Nesta página