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.
| Camada | O que ela estiliza | Como você estiliza |
|---|---|---|
| Dentro do iframe | O texto do input, o placeholder e o cursor renderizados pelo campo seguro | Objeto ElementStyle passado como style |
| Ao redor do iframe | Bordas, padding, fundo, anel de foco, estados de validação | Seu 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.
| Propriedade | Type | Descrição |
|---|---|---|
color | string | Cor do texto do valor do input (qualquer cor CSS). |
fontSize | string | Tamanho da fonte do texto do input, por exemplo "16px". |
fontFamily | string | Pilha de fontes para o texto do input. Veja Carregando fontes personalizadas. |
fontWeight | string | Peso da fonte, por exemplo "400" ou "600". |
lineHeight | string | Altura 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.
| Seletor | Alvo |
|---|---|
::placeholder | O texto do placeholder exibido enquanto o campo está vazio. |
:focus | O 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.
| Estado | Aplicado quando | Uso típico |
|---|---|---|
empty | O campo ainda não tem valor | Suavizar a cor do cursor/texto antes do input |
complete | O valor está completo e válido | Confirmar sucesso com um tom verde |
invalid | O valor atual falha na validação | Alertar 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:
: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.- 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
- Visão geral do Bridge SDK — instale o SDK e crie elementos.
- Tokenização — transforme os dados coletados do cartão em uma referência de token.
- Autenticação — chaves públicas vs. secretas e onde cada uma se aplica.