Skip to content

Tudo para WordPress, desenvolvimento web — e não só

📱 Máscara de input de telefone em JavaScript: 4 métodos com código

📱 Máscara de input de telefone em JavaScript: 4 métodos com código

Os utilizadores introduzem números de telefone de todas as maneiras: alguns começam com 8, outros com +7, uns escrevem os dígitos sem espaços, outros acrescentam espaços a cada dois dígitos. A base de dados acaba numa confusão. Os gestores perdem tempo a fazer chamadas e metade dos números revela-se inválida. Um cenário familiar para qualquer pessoa que já tenha adicionado um formulário de contacto a um website.

Uma máscara de introdução resolve este problema por completo: o utilizador fica fisicamente impedido de introduzir um número no formato errado. Escreve os dígitos e estes aparecem automaticamente nos sítios certos, enquanto parênteses e hífens surgem por si. Sem erros, sem frustração.

Abaixo estão quatro formas de adicionar uma máscara de telefone a um campo: desde HTML5 nativo, sem JavaScript, até uma biblioteca completa com bandeiras para todos os países. Com código que pode copiar e colar no seu projeto.

💡 Resumo rápido:

  • A máscara mais simples usa o atributo pattern e type="tel", sem qualquer JavaScript, funciona em qualquer navegador
  • Se precisa de bandeiras de países e formatação internacional, use intl-tel-input, a solução mais popular no GitHub
  • Se precisa de uma biblioteca para telefones, datas, cartões e outras máscaras, opte por IMask.js
  • Se quer escrever uma máscara manualmente sem adicionar dependências, JavaScript puro resolve em 30 linhas

O que é uma máscara de introdução e porque é mais importante do que a validação

Uma máscara de introdução é uma string modelo que controla o que o utilizador vê e pode escrever num campo de formulário. Ao contrário da validação, que verifica os dados após o envio e mostra um erro, uma máscara atua em tempo real durante a introdução: impede que se escreva uma letra onde deveria estar um dígito e insere automaticamente parênteses, hífens e espaços.

A diferença é fundamental. A validação diz «cometeu um erro» e o utilizador já está frustrado e pode abandonar. Uma máscara guia-o passo a passo: os erros são simplesmente impossíveis. Para números de telefone isto é crítico, porque existem dezenas de opções de formatação. Só um número russo pode ser escrito como +7 999 123-45-67, como 8(999)1234567 ou como +7(999)123-45-67, e estas são apenas três variantes entre muitas. Sem uma máscara, cada utilizador inventa o seu próprio formato e a base de dados transforma-se num depósito de lixo.

Método 1: HTML5, type="tel" e pattern

O caminho mais fácil: dispensar completamente o JavaScript. Os navegadores modernos suportam type="tel" e o atributo pattern, que valida a introdução de dados contra uma expressão regular no envio do formulário.

Adicione o campo ao seu markup. O código pode ser inserido em qualquer template HTML: Contact Form 7, um formulário nativo do WordPress ou markup personalizado.

1<input
2 type="tel"
3 id="phone"
4 name="phone"
5 pattern="\+7\s?[\(]?\d{3}[\)]?\s?\d{3}[\-]?\d{2}[\-]?\d{2}"
6 placeholder="+7 (999) 123-45-67"
7 title="Enter the number in the format +7 (999) 123-45-67"
8 required
9>

Vamos analisar o que está a acontecer aqui. type="tel" mostra um teclado numérico em dispositivos móveis em vez do teclado normal, tornando a introdução do telefone mais conveniente. pattern define uma expressão regular que permite várias variantes: com ou sem espaços, com ou sem parênteses à volta do indicativo de área. title mostra uma dica ao passar o rato e required impede o envio do formulário com o campo vazio.

A vantagem: zero dependências, funciona em qualquer navegador. Para uma landing page simples, isto é suficiente.

Mas isto não é uma máscara verdadeira. Os parênteses e hífens não aparecem automaticamente; o utilizador tem de os escrever manualmente. O pattern só é acionado no envio do formulário. Se precisa de formatação em tempo real durante a introdução, avance para os próximos métodos.

Método 2: intl-tel-input, formato internacional com bandeiras de países

intl-tel-input é a biblioteca JavaScript mais popular para introdução de telefones. Fornece um campo com uma lista suspensa de bandeiras de países, formatação automática para corresponder ao modelo nacional e validação do número. Em junho de 2026, a biblioteca tinha mais de 7.800 estrelas no GitHub e a versão atual é a 29.

Instale a biblioteca via npm (npm i intl-tel-input) ou CDN. O código abaixo é para JavaScript vanilla; também existem componentes prontos para React, Vue, Angular e Svelte.

1<!-- In the <head> of the page -->
2<link
3 rel="stylesheet"
4 href="https://cdn.jsdelivr.net/npm/intl-tel-input@29/build/css/intlTelInput.css"
5>
6<script src="https://cdn.jsdelivr.net/npm/intl-tel-input@29/build/js/intlTelInput.min.js"></script>

O elemento de input e a inicialização vão no template onde precisa do campo. Para um tema WordPress, adicione o script via wp_enqueue_script no functions.php e coloque o markup no template apropriado.

1<input type="tel" id="phone">
2
3<script>
4 const input = document.querySelector("#phone");
5 const iti = intlTelInput(input, {
6 initialCountry: "ru",
7 separateDialCode: true,
8 utilsScript: "https://cdn.jsdelivr.net/npm/intl-tel-input@29/build/js/utils.js"
9 });
10</script>

initialCountry: "ru" define a bandeira russa por defeito. separateDialCode: true move o código do país para fora do campo de input: quando o utilizador muda a bandeira, o código é inserido automaticamente. utilsScript carrega utilitários de formatação; sem eles a biblioteca ainda funciona, mas os números não são formatados para corresponder ao padrão do país selecionado.

O objeto devolvido por intlTelInput() fornece vários métodos úteis. iti.getNumber() devolve o número no formato internacional E.164, iti.isValidNumber() verifica a validade e iti.setNumber("9991234567") define o valor programaticamente. Para o Contact Form 7 vai precisar de um script personalizado: encontre o campo .wpcf7-tel e anexe-lhe o intlTelInput.

Vantagem: uma solução internacional completa com formatação automática, bandeiras, validação e integrações com frameworks. Desvantagem: a biblioteca pesa cerca de 40 KB (gzip), o que é excessivo para uma landing page simples com um único campo.

Método 3: IMask.js, uma máscara universal sem jQuery

IMask.js é uma biblioteca de máscaras madura escrita em JavaScript puro: sem jQuery, sem outras dependências. Suporta máscaras para telefones, datas, números, moedas e modelos dinâmicos. É útil quando precisa de diferentes tipos de máscaras num site: um telefone num formulário de contacto, uma data num calendário e um montante numa calculadora. A versão atual é a 7.1.

Instale via npm (npm i imask) ou inclua o CDN:

1<script src="https://unpkg.com/imask"></script>

Uma máscara de telefone em três linhas. O código pode ir numa tag <script> no footer ou num ficheiro JS separado no seu tema.

1const phoneInput = document.getElementById('phone');
2const maskOptions = {
3 mask: '+{7} (000) 000-00-00'
4};
5IMask(phoneInput, maskOptions);

Sintaxe da máscara: +{7} é um prefixo fixo que o utilizador não pode editar. 0 representa qualquer dígito de 0 a 9. Pode adicionar complexidade: tornar o indicativo de área opcional ou mudar dinamicamente a máscara quando o país muda, usando o parâmetro dispatch.

O IMask devolve um objeto com acesso ao valor bruto: maskRef.unmaskedValue dar-lhe-á os dígitos simples 79991234567, exatamente o que quer guardar na base de dados. O método maskRef.value devolve a string formatada para exibição. O problema clássico está resolvido: os dígitos vão para o backend, enquanto o utilizador vê um número bem formatado.

Vantagem: uma biblioteca para todos os casos, valores brutos prontos a usar, sem dependências. Desvantagem: para um único campo de telefone é mais fácil usar intl-tel-input com bandeiras; o IMask brilha realmente em formulários com três a cinco tipos de campos diferentes.

Método 4: JavaScript puro, uma máscara artesanal

Se não quiser adicionar uma biblioteca apenas para um campo, escreva a máscara em JavaScript puro. O código abaixo trata cada tecla premida e insere automaticamente parênteses e hífens à medida que os dígitos são introduzidos.

Coloque o script no mesmo template onde está o campo de input ou inclua-o como um ficheiro separado. Para WordPress, use wp_enqueue_script com a flag true (no footer).

1document.getElementById('phone').addEventListener('input', function (e) {
2 let value = e.target.value.replace(/\D/g, '');
3
4 if (value.length > 11) {
5 value = value.slice(0, 11);
6 }
7
8 let formatted = '+7 (';
9 if (value.length > 1) formatted += value.slice(1, 4);
10 if (value.length > 4) formatted += ') ' + value.slice(4, 7);
11 if (value.length > 7) formatted += '-' + value.slice(7, 9);
12 if (value.length > 9) formatted += '-' + value.slice(9, 11);
13
14 e.target.value = formatted;
15});

O evento input é disparado a cada alteração no campo: colar da área de transferência, autocorreção, eliminação. A primeira linha replace(/\D/g, '') remove tudo exceto dígitos: letras e caracteres especiais desaparecem instantaneamente. Depois, o script corta os dígitos em excesso (um número russo tem 11 dígitos, incluindo o código do país) e constrói a string formatada: código do país +7, indicativo de área de três dígitos entre parênteses, três dígitos, dois, dois, separados por hífens.

Antes de usar isto num site ativo, adicione duas melhorias. Primeiro: ao apagar dígitos no meio do número, o cursor pode saltar para o fim do campo; guarde a posição do cursor via selectionStart e restaure-a após a formatação. Segundo: para números de outros países (a Bielorrússia tem 12 dígitos, o Cazaquistão tem 11 dígitos com um código diferente) a lógica torna-se mais complexa e, nesse ponto, o intl-tel-input é plenamente justificado.

Vantagem: 30 linhas, controlo total, zero kilobytes de dependências. Desvantagem: a máscara é feita à medida para um formato; para projetos multinacionais, o código vai inchar.

⁉️🤔 Perguntas frequentes

Porque é que uma máscara é melhor do que uma simples validação?

A validação é acionada após o envio do formulário: o utilizador vê um erro e tem de voltar atrás para o corrigir. Uma máscara funciona durante a introdução, tornando um formato inválido fisicamente impossível. Menos frustração, menos formulários abandonados. Para números de telefone isto é crítico: os erros no número são uma das razões mais comuns para os utilizadores abandonarem um formulário.

Como guardo dígitos simples na base de dados, sem parênteses e hífens?

Todas as bibliotecas neste artigo fornecem valores brutos: o intl-tel-input tem um método getNumber() que devolve +79991234567, o IMask.js tem uma propriedade unmaskedValue que devolve 79991234567. Antes de enviar os dados para o servidor, obtenha o valor bruto e guarde-o. Mostre a string formatada apenas na interface. Em formulários WordPress, adicione um campo oculto <input type="hidden" name="phone_raw"> e preencha-o via JavaScript antes do envio.

A máscara funciona em dispositivos móveis?

Sim, todos os quatro métodos funcionam corretamente em iOS e Android. type="tel" faz aparecer o teclado numérico, o que é conveniente. Em Android mais antigo (versões abaixo da 6), o evento input pode comportar-se de forma diferente com a autocorreção; teste em dispositivos reais. O intl-tel-input e o IMask.js são testados pelos seus programadores em navegadores móveis e não causam problemas.

Posso usar uma máscara com o Contact Form 7?

O CF7 gera campos com classes .wpcf7-tel. Escreva um script que encontre este campo por seletor e lhe anexe o intl-tel-input ou o IMask. No envio do formulário, o CF7 obtém o valor diretamente do campo, pelo que a biblioteca tem de ter tempo para o formatar previamente. Se usar valores brutos, intercete o evento wpcf7submit e substitua os dados num campo oculto.

O que devo fazer com números de diferentes países no mesmo site?

Use o intl-tel-input: o utilizador seleciona uma bandeira e a máscara muda automaticamente para corresponder ao formato do país escolhido. Para geotargeting, pode definir initialCountry: "auto" e a biblioteca detetará o país por IP através de um serviço externo. Se houver apenas dois ou três países e o seu orçamento de dependências for mínimo, escreva duas máscaras em JavaScript puro e alterne entre elas com um botão de rádio «Rússia / Cazaquistão» acima do campo.

Qual o método a escolher para a sua tarefa

A escolha resume-se a três perguntas: quantos campos existem no site, precisa de bandeiras de países e quão crítico é o tamanho do pacote.

Um único formulário simples numa landing page: comece com o pattern do HTML5. Rápido, sem JavaScript e, no telemóvel, o teclado muda para numérico. Se o site aceitar números internacionais, o intl-tel-input cobrirá tudo: bandeiras, formatação automática, validação. Para uma loja online ou SaaS, este é o padrão.

Várias máscaras diferentes no site (telefone, data, montante, cartão): o IMask.js dar-lhe-á uma API para todos os campos e não requer jQuery. Está a construir um projeto pessoal e quer controlo total: 30 linhas de JavaScript puro tratarão dos números russos sem uma única dependência.

Teste como a máscara funciona num site ativo: introduza um número com letras, cole da área de transferência, tente apagar alguns dígitos no meio. O campo deve comportar-se de forma previsível em qualquer cenário. Que método escolheu para o seu projeto? Partilhe nos comentários.