Máscara de CPF, CNPJ, CEP e telefone em JavaScript
Uma máscara de formulário põe os pontos, traços e parênteses enquanto a pessoa digita, sem impedir que ela cole o valor já formatado. Este guia traz máscaras de CPF, CNPJ (inclusive o novo formato com letras), CEP e telefone em JavaScript puro, sem biblioteca, os atributos de HTML que ajudam no celular e a formatação para exibição em Python e PHP.
Como a máscara funciona
A cada tecla, a máscara tira tudo que não é dígito, corta no tamanho máximo e põe a pontuação de novo. Como ela sempre parte dos dígitos, funciona igual para quem digita, quem cola 52998224725 e quem cola 529.982.247-25. Cada regra só aplica a pontuação quando já há dígitos depois dela, então o valor pela metade também sai certo.
A máscara cuida só do formato. Para saber se o número é válido, confira os dígitos verificadores, como no validador de CPF e no validador de CNPJ.
As máscaras em JavaScript
O telefone troca de formato no 11º dígito: com 10 dígitos é fixo, (11) 3123-4567, e com 11 é celular, (11) 91234-5678. O CNPJ aceita letras nas 12 primeiras posições, como no formato alfanumérico que a Receita usa desde julho de 2026.
const soDigitos = (v) => v.replace(/\D/g, '');
// Cada máscara aceita o valor pela metade, para ser aplicada enquanto a pessoa digita
const mascaras = {
cpf: (v) =>
soDigitos(v)
.slice(0, 11)
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d{1,2})$/, '$1-$2'),
// CNPJ numérico e alfanumérico (letras nas 12 primeiras posições)
cnpj: (v) =>
v
.toUpperCase()
.replace(/[^0-9A-Z]/g, '')
.slice(0, 14)
.replace(/^(\w{2})(\w)/, '$1.$2')
.replace(/^(\w{2})\.(\w{3})(\w)/, '$1.$2.$3')
.replace(/\.(\w{3})(\w)/, '.$1/$2')
.replace(/(\w{4})(\w)/, '$1-$2'),
cep: (v) => soDigitos(v).slice(0, 8).replace(/(\d{5})(\d)/, '$1-$2'),
// Fixo com 10 dígitos e celular com 11: o formato muda no 11º dígito
telefone: (v) => {
const d = soDigitos(v).slice(0, 11);
if (d.length === 11) return d.replace(/(\d{2})(\d{5})(\d{4})/, '($1) $2-$3');
return d.replace(/(\d{2})(\d)/, '($1) $2').replace(/(\d{4})(\d)/, '$1-$2');
},
};
function aplicarMascara(input, tipo) {
input.addEventListener('input', () => {
input.value = mascaras[tipo](input.value);
});
} Uso: aplicarMascara(document.querySelector("#cpf"), "cpf").
Os atributos de HTML que ajudam
- Use
type="text", e nãotype="number": o campo de número tira os zeros à esquerda do CEP e do CPF e mostra setas de aumentar e diminuir. inputmode="numeric"abre o teclado numérico no celular para CPF, CEP e telefone. Não use no CNPJ, que agora pode ter letras.autocomplete="postal-code"no CEP eautocomplete="tel-national"no telefone deixam o navegador preencher sozinho.maxlengthcom o tamanho já formatado: 14 para CPF, 18 para CNPJ, 9 para CEP e 15 para telefone.
Formatar para exibição em Python e PHP
No servidor, guarde só os dígitos e formate na hora de mostrar. As funções abaixo devolvem o valor original quando o tamanho não fecha, para não esconder um dado errado com uma máscara.
import re
def formatar_cpf(valor: str) -> str:
d = re.sub(r"\D", "", valor)
return f"{d[:3]}.{d[3:6]}.{d[6:9]}-{d[9:11]}" if len(d) == 11 else valor
def formatar_cnpj(valor: str) -> str:
c = re.sub(r"[^0-9A-Z]", "", valor.upper())
return f"{c[:2]}.{c[2:5]}.{c[5:8]}/{c[8:12]}-{c[12:14]}" if len(c) == 14 else valor
def formatar_telefone(valor: str) -> str:
d = re.sub(r"\D", "", valor)
if len(d) == 11:
return f"({d[:2]}) {d[2:7]}-{d[7:]}"
if len(d) == 10:
return f"({d[:2]}) {d[2:6]}-{d[6:]}"
return valor <?php
function formatarCpf(string $valor): string
{
$d = preg_replace('/\D/', '', $valor);
if (strlen($d) !== 11) {
return $valor;
}
[$a, $b, $c, $dv] = [substr($d, 0, 3), substr($d, 3, 3), substr($d, 6, 3), substr($d, 9, 2)];
return "$a.$b.$c-$dv";
}
function formatarCep(string $valor): string
{
$d = preg_replace('/\D/', '', $valor);
return strlen($d) === 8 ? substr($d, 0, 5) . '-' . substr($d, 5) : $valor;
} Cuidados
- Mande para o servidor só os dígitos (remova a máscara antes de enviar) e valide de novo lá. A máscara no navegador não protege nada.
- Trocar o valor do campo a cada tecla move o cursor para o fim. Se a pessoa corrigir um dígito no meio, ela perde a posição; para a maioria dos formulários isso é aceitável, mas leitores de tela podem anunciar o valor inteiro a cada tecla.
- Para validar o formato completo, use as expressões do guia de regex para CEP, telefone e e-mail.
- Para gerar números válidos para testar o formulário, veja como gerar CPF e CNPJ para testes.
Achou um erro neste guia? Avise por e-mail.
Perguntas frequentes
Como fazer máscara de CPF em JavaScript sem biblioteca?
A cada evento input, tire o que não é dígito, corte em 11 dígitos e reponha os pontos e o traço com replace. A função deste guia faz isso e funciona tanto digitando quanto colando o CPF formatado.
Como fazer máscara de telefone que aceite fixo e celular?
Formate como fixo, (11) 3123-4567, até 10 dígitos, e troque para celular, (11) 91234-5678, quando a pessoa digitar o 11º. É o que a máscara deste guia faz.
A máscara de CNPJ precisa mudar por causa do CNPJ alfanumérico?
Precisa aceitar letras nas 12 primeiras posições e não usar teclado só numérico. A pontuação continua a mesma: 12.ABC.345/01DE-35.
Devo salvar o CPF com ou sem máscara no banco?
Sem máscara, só com os dígitos. Assim a busca e a comparação funcionam sempre, e a máscara é aplicada na hora de exibir.
Outros guias
- Regex para CEP, telefone e e-mail no BrasilExpressões regulares para validar CEP, telefone com DDD e e-mail, com os erros que deixam passar valores inválidos em JavaScript, Python e PHP.
- Como gerar CPF e CNPJ válidos para testes em códigoComo gerar CPF e CNPJ matematicamente válidos para testes em JavaScript, Python e PHP, o cálculo dos dígitos e os cuidados para não usar dados de pessoas reais.
- CNPJ alfanumérico: o que muda e como validar em códigoEntenda o CNPJ alfanumérico (letras e números), o que muda para quem desenvolve e veja funções testadas para validar em JavaScript, Python e PHP.