O Gerador De CPF O Gerador De CPF

Máscara de CPF com JavaScript Puro (Sem Dependências)

Função JavaScript pura para formatar CPF no padrão XXX.XXX.XXX-XX em tempo real, como a usada na página de geração de CPF. Sem jQuery, sem dependências, apenas a API nativa do DOM.

Código

function formatCPF(value) {
  var digits = value.replace(/\D/g, '').slice(0, 11);
  if (digits.length <= 3) return digits;
  if (digits.length <= 6) return digits.slice(0, 3) + '.' + digits.slice(3);
  if (digits.length <= 9)
    return digits.slice(0, 3) + '.' + digits.slice(3, 6) + '.' + digits.slice(6);
  return (
    digits.slice(0, 3) +
    '.' +
    digits.slice(3, 6) +
    '.' +
    digits.slice(6, 9) +
    '-' +
    digits.slice(9)
  );
}

function applyMask(input) {
  input.addEventListener('input', function () {
    var pos = input.selectionStart;
    var prev = input.value.length;
    input.value = formatCPF(input.value);
    var diff = input.value.length - prev;
    input.setSelectionRange(pos + diff, pos + diff);
  });
}

Análise do código

formatCPF remove todos os caracteres não numéricos com replace(/\D/g, ''), limita a 11 dígitos com slice(0, 11) e insere pontos e traço de acordo com o comprimento da string. A formatação é progressiva: 3 dígitos → sem separador, 4 a 6 → primeiro ponto, 7 a 9 → segundo ponto, 10 a 11 → traço.

applyMask registra um listener no evento input. A cada digitação, salva a posição do cursor (selectionStart), aplica a formatação, e corrige a posição do cursor com a diferença de comprimento gerada pelos separadores inseridos. Isso evita que o cursor salte para o final do campo.

Uso

HTML:

<input type="text" id="cpf" inputmode="numeric" placeholder="000.000.000-00" />

<script>
  applyMask(document.getElementById('cpf'));
</script>

Resultado ao digitar:

formatCPF('529');          // "529"
formatCPF('529982');       // "529.982"
formatCPF('52998224725');  // "529.982.247-25"

Também funciona para formatar um valor já existente:

formatCPF('52998224725');  // "529.982.247-25"
formatCPF('000.000.001-91'); // "000.000.001-91"

Testes

Testes com Vitest ou Jest:

import { describe, it, expect } from 'vitest';

describe('formatCPF', () => {
  it('retorna vazio para string sem dígitos', () => {
    expect(formatCPF('')).toBe('');
    expect(formatCPF('abc')).toBe('');
  });

  it('não formata até 3 dígitos', () => {
    expect(formatCPF('5')).toBe('5');
    expect(formatCPF('52')).toBe('52');
    expect(formatCPF('529')).toBe('529');
  });

  it('insere primeiro ponto após 3 dígitos', () => {
    expect(formatCPF('5299')).toBe('529.9');
    expect(formatCPF('529982')).toBe('529.982');
  });

  it('insere segundo ponto após 6 dígitos', () => {
    expect(formatCPF('5299822')).toBe('529.982.2');
    expect(formatCPF('529982247')).toBe('529.982.247');
  });

  it('insere traço após 9 dígitos', () => {
    expect(formatCPF('5299822472')).toBe('529.982.247-2');
    expect(formatCPF('52998224725')).toBe('529.982.247-25');
  });

  it('limita a 11 dígitos', () => {
    expect(formatCPF('529982247251234')).toBe('529.982.247-25');
  });

  it('remove caracteres não numéricos da entrada', () => {
    expect(formatCPF('529.982.247-25')).toBe('529.982.247-25');
    expect(formatCPF('abc529def982ghi')).toBe('529.982');
  });
});

Precisa de CPFs para testar a máscara? O gerador de CPF cria números válidos com ou sem formatação.

Veja também: validar CPF em JavaScript.