Máscaras de entrada e formulário UX
1) Princípios
1. Ajudar, não punir. A máscara direciona a digitação e reduz os erros, mas não bloqueia a impressão e a inserção.
2. Dados ≠ exibição. Guardemos os valores «crus» normalizados, formatamos apenas em UI.
3. Cursor previsível. Qualquer substituição automática não «salta» caret ou quebra undo/redo.
4. Local e dispositivo. Teclados, separadores, calendário e divisas - por região e plataforma.
5. Disponibilidade e privacidade. Texto + ícone/cor; camuflamos os campos sensíveis, mas não atrapalhamos os gerentes de senhas/controle automático.
2) Quando a máscara é apropriada (e quando não)
Usar:- Formatos com estrutura sustentável: telefone, IBAN, PAN (cartões), CVC, data, hora, índice, OTP.
- Quantias em dinheiro com separadores (digitação «limpa» na impressão e formato no prato).
- Códigos (ref. códigos, promo), comprimentos fixos.
- Nomes/endereços/email (a máscara limita caracteres/idiomas válidos).
- Campos livres complexos (comentários, nomes de empresas).
- Digitar com um formato potencialmente desconhecido (números internacionais sem país).
3) Máscara vs formato automático vs validação
A máscara é a dica da estrutura em voo (parênteses, defeitos); não deve quebrar a entrada/inserção.
Formato automático - Use no prato/perda de foco (milhares, espaços IBAN).
Validação - lógica de correção (comprimento, somas de controle), exibição de erros após 'blur' ou 'submit'.
Regra: A máscara não substitui a validação, e o formato automático não deve alterar o significado.
4) Teclados e atributos HTML
Coloque os tipos/modos corretos para acelerar a digitação e reduzir os erros:5) Caret, copaço e normalização
Não quebrar caret: ao inserir automaticamente caracteres (espaços/parênteses), ajuste a posição do cursor.
Copie: Ao inserir, limpe os espaços/defeitos → valide → exibe com formatação.
Normalização: trimming, substituição de «curvas» de caracteres ('O'→'0' não pode!), tradução para maiúscula superior do IBAN, formato de data único no armazenamento (ISO).
js const clean = s => s. replace(/[^\da-zA-Z]/g,'');
const normalizePAN = s => clean(s). slice (0.19) ;//no spaces/hyphens const normalizeIBAN = s => clean (s). toUpperCase(); // A–Z0–9
6) Números, divisas e locais
Digite «como é impresso» (tolerância «,» ou «.» como separador), armazenado em menores units (centavos/centavos).
Exibição por localização (agrupamento de milhares) no prato/depois do sabmite; no foco, mostre o valor «cru» para a facilidade de edição.
Especifique claramente a moeda e fixe a precisão (por exemplo, 2 caracteres).
js function parseMoney(input) {
//resolve both comma and period as decimal const s = input. replace(/\s/g,''). replace(',', '.');
const num = Number(s);
if (Number. isNaN(num)) return null;
return Math. round(num 100); // cents
}
function formatMoney(cents, locale='ru-RU', currency='RUB') {
return (cents/100). toLocaleString(locale, { style:'currency', currency });
}
7) Datas e horários
Se os píeres nativos forem desconfortáveis/diferentes nas plataformas, use a caixa de texto com máscara 'DD. MM. YYYY ', mas guarde o ISO' YYYY-MM-DD '.
Verificar a realidade das datas (29. 02, faixa), temporizões, no servidor.
Adicione os botões Hoje, Agora, Limpar.
8) Telefones e países
Dois campos: país (+ código) e número ou máscara inteligente para o país escolhido.
Ao inserir «+ CC...» completo, complete o país.
Guarde o E.164 ('+ CCXXXXXXXX') e mostre localmente com espaços.
9) Adereços de pagamento: PAN/IBAN/CVC/EXP
PAN: agrupamento 4-4-4-4/4; no valor, apenas números; Luhn-check; sem logs/analistas com PAN.
O CVC: 'spd' (oculto), 'autocomplete =' cc-csc '', não será salvo em rascunhos.
EXP: 'MM/YY', inserção automática '/' após 2 dígitos, verificação da faixa 01-12 e um ano razoável.
IBAN: upper-case, espaços apenas na UI; verificação do comprimento nacional e do valor de referência.
10) RT/código de confirmação
6 (ou N) células automáticas e de transição automática, a inserção do tampão reconhece todo o código.
'autocomplete =' one-time-código ', e no celular, extração automática de SMS.
A entrada de Bacap sem campos de split (um campo) é para screeners.
html
<div class="otp" role="group" aria-label="Код из SMS">
<input inputmode="numeric" maxlength="1">
<input inputmode="numeric" maxlength="1">
<!-- … -->
</div>
11) Máscaras e a11y
A editora é obrigatória ('<label for>'), o placeholder é um exemplo e não um substituto.
Explique a regra ao lado: helper text com exemplo («Formato: + CC XXX-XXX-XXX»).
Os erros são associados através de 'ária-describedy', e críticos, 'role =' alert '.
Contraste de texto e contornos ≥ AA, ': focus-visível' não ocultar.
12) Privacidade e segurança
Campos sensíveis: não logar, não escrever em RUM, não salvar em rascunhos (PAN, CVC, passaporte).
Máscaras e formatação não devem revelar a validade da conta («Se o email estiver registrado...» - linguagem neutra).
Idempotidade e retry para sabmites críticos (pagamento/taxa).
13) Comportamento de formulário e desempenho
Debouns de verificação asincrona (250-400 ms), indicador visível «Verificando»....
Não bloqueie a tela inteira por um campo; spinner local/esqueleto.
Batchite alterações DOM; Anime apenas 'transfm/opacity'.
No celular, evite «saltos» quando o teclado aparecer (safe-area, viewport meta).
14) Código-snippets
Máscara macia do telefone (sem quebra de inserção):js function formatPhoneVisible(value) {
const d = value. replace(/\D/g,''). slice(0,15);
if (!d) return '';
if (d. startsWith('7') d. startsWith('8')) {
return d. replace(/^([78])? (\d{3})(\d{3})(\d{2})(\d{2})./, '+7 ($2) $3-$4-$5');
}
// generic E.164 grouping: +CC XXX XXX XX XX return d. replace(/^(\d{1,3})(\d{0,3})(\d{0,3})(\d{0,2})(\d{0,2})./, (m,c1,c2,c3,c4,c5)=>
`+${c1}${c2?` ${c2}`:''}${c3?` ${c3}`:''}${c4?` ${c4}`:''}${c5?` ${c5}`:''}`.trim());
}
const input = document. querySelector('#phone');
input. addEventListener('input', e => {
const raw = e. target. value;
const pos = e. target. selectionStart;
const digitsBefore = raw. slice(0,pos). replace(/\D/g,''). length;
const cleaned = raw. replace(/[^\d+]/g,'');
const visible = formatPhoneVisible(cleaned);
e. target. value = visible;
// restore caret by counting digits let p = 0, count = 0;
while (p < e. target. value. length && count < digitsBefore) { if (/\d/.test(e. target. value[p])) count++; p++; }
e. target. setSelectionRange(p, p);
});
Soma: «Formato cru no foco → no prato»:
js const amount = document. getElementById('amount');
let cents = null;
amount. addEventListener('focus', () => {
if (cents!=null) amount. value = String(cents/100). replace('.', ',');
});
amount. addEventListener('blur', () => {
const v = parseMoney(amount. value) ;//from section 6 if (v = = null) return; cents = v;
amount. value = formatMoney(cents, 'ru-RU', 'RUB');
});
BAN: upper-case e agrupamento no prato:
js const iban = document. getElementById('iban');
iban. addEventListener('input', () => iban. value = iban. value. toUpperCase());
iban. addEventListener('blur', () => {
const raw = normalizeIBAN(iban. value);
iban. dataset. raw = raw ;//for iban submission. value = raw. replace(/(.{4})/g,'$1 '). trim () ;//view only
});
15) Sistema de design de tokens (exemplo)
json
{
"input": {
"radius": 10,
"height": { "sm": 36, "md": 40, "lg": 48 },
"gap": 8,
"icon": 16
},
"mask": {
"debounceMs": 300,
"otpLength": 6,
"moneyPrecision": 2,
"phoneMaxDigits": 15
},
"a11y": {
"focusRing": { "width": 2, "offset": 2 },
"contrastAA": true
}
}
Os presídios CSS:
css
.input { height:40px; padding:0 12px; border-radius:10px; }
.input:focus-visible { outline:2px solid var(--focus-ring); outline-offset:2px; }
.field-error { color: var(--role-danger); font-size:.875rem; margin-top:6px; }
.otp input { width:40px; text-align:center; }
16) Especificidades iGaming
Pagamentos/conclusões: PAN/IBAN/amount com máscaras moles; Idimpotência rigorosa e falta de logs de campos sensíveis; Dicas sobre comissões e prazos.
KYC: máscaras para datas, números de passaporte (sem filtragem «rígida» - contabilidade de diferentes formatos), tamanho/tipo de arquivo, pré-teste.
Limites e jogo responsável: quantias/períodos compreensíveis (dias/semanas/meses), helpers ao lado, contraste AAA.
Apostas: digitação rápida do valor (botões-predial + campo), focado em número cru, com formato por localização; «, «...../separador duplo.
17) Anti-pattern
Máscaras rígidas que impedem caracteres/inserção válidos.
Caret saltável no formato automático; falta da seleção/undo.
Placeholder em vez da editora.
Adição automática de moeda para dentro do valor (quebra o copypast).
Erros de cada símbolo sem debouns.
Formatos localizáveis no armazém (armazene ISO/números).
Logar os números do PAN/passaporte e mostrar as razões «demasiado justas» para o desvio.
18) Métricas e experiências
Erro rate por campo (antes/depois da máscara).
O Time-to-Complete e os formulários de reencontro.
Proporção de colagens falhadas (copypast) e «repostos» (undo).
CTR dicas/exemplos, taxa de reposição automática.
Abandon rate na etapa de pagamento/CUS.
19) QA-folha de cheque
Entrada e caret
- A inserção do tampão não é quebrada, os espaços/defeitos são limpados corretamente.
- Caret permanece previsível após o formato automático.
Local e formato
- As quantias permitem ', '/'; armazenamento em menores units.
- As datas são paradas e validadas; armazenamento em ISO.
A11y
- Editoras e 'ária-describedy' estão conectadas; 'role =' alert 'para críticos.
- O contraste e os anéis de foco correspondem a AA.
Segurança
- Os campos sensíveis não são logados ou não são armazenados.
- Idempotidade e retry em passos críticos.
UX
- Placeholder é um exemplo, não uma editora; helper ao lado.
- As máscaras não impedem a impressão no celular; teclados corretos ('inputmode').
20) Documentação em design
Компоненты: `MaskedInput`, `MoneyInput`, `PhoneInput`, `OtpInput`, `IbanInput`.
Toquins de máscaras (comprimentos/modelos), regras de caret/inserção, localização de números/datas.
Guidas por privacidade (o que não é logado), por disponibilidade e pelo formato vs prato automático.
«Do/Don 't» com exemplos e métricas reais antes/depois.
Resumo curto
Máscaras e formas são boas quando eles aceleram a digitação, mantêm os dados limpos e não atrapalham. Formate com cuidado, normalize na entrada, armazene em espécies estáveis, leve em conta locais e disponibilidade. Os formulários tornam-se rápidos e compreensíveis, especialmente em cenários sensíveis de pagamento, KYC e apostas.