# Como criar um fluxo de verificação de CPF acessível para pessoas com deficiência

> Aprenda a criar fluxos de verificação de CPF acessíveis para pessoas com deficiência, seguindo WCAG e boas práticas de acessibilidade web.

**Publicado:** 23/03/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-criar-um-fluxo-de-verificacao-de-cpf-acessivel-para-pessoas-com-deficiencia

---


Um fluxo acessível de verificação de CPF requer: label associado programaticamente ao campo via `for`/`id`, `aria-describedby` apontando para mensagens de instrução e erro, `role="alert"` no elemento de feedback para anúncio imediato por leitores de tela, indicador de foco visível em CSS e área de toque mínima de 44×44px. Esses cinco elementos cobrem os critérios WCAG mais críticos para esse tipo de formulário.

## Introdução

Segundo o IBGE, mais de 18 milhões de brasileiros têm algum tipo de deficiência. Quando um fluxo de verificação de CPF não é acessível, essas pessoas ficam excluídas de serviços essenciais como abertura de contas, compras online e cadastros em plataformas digitais. Acessibilidade não é apenas uma obrigação legal — a [Lei Brasileira de Inclusão (Lei 13.146/2015)](https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2015/lei/l13146.htm) e as diretrizes WCAG estabelecem padrões que todo serviço digital deve cumprir. É também um compromisso com a experiência de todos os usuários.

---

## Requisitos de acessibilidade para campos de CPF

As diretrizes WCAG (Web Content Accessibility Guidelines) estabelecem critérios que se aplicam diretamente a campos de formulário. Para o campo de CPF, os critérios mais relevantes são:

* **1.3.1 Informações e relações** — A estrutura do formulário deve ser programaticamente determinável. Labels devem estar associados aos campos.

* **1.4.3 Contraste mínimo** — O texto deve ter uma razão de contraste de pelo menos 4.5:1 com o fundo.

* **2.1.1 Teclado** — Toda funcionalidade deve ser operável via teclado.

* **3.3.1 Identificação de erro** — Se um erro é detectado, o item com erro deve ser identificado e o erro descrito em texto.

* **3.3.2 Labels ou instruções** — Labels ou instruções devem ser fornecidos quando o conteúdo requer entrada do usuário.

* **4.1.2 Nome, função, valor** — Componentes de interface devem ter nome e função programaticamente determináveis.

---

## Label e associação programática

O elemento mais fundamental da acessibilidade em formulários é a associação correta entre label e input:

```html
<div class="campo-cpf">
 <label for="cpf">CPF</label>
 <input
 type="text"
 id="cpf"
 name="cpf"
 inputmode="numeric"
 placeholder="000.000.000-00"
 aria-required="true"
 aria-describedby="cpf-instrucao cpf-mensagem"
 autocomplete="off"
 />
 <span id="cpf-instrucao" class="instrucao">
 Informe os 11 dígitos do seu CPF. A formatação é aplicada automaticamente.
 </span>
 <span id="cpf-mensagem" class="mensagem" role="alert" aria-live="assertive">
 </span>
</div>
```

### Pontos essenciais

* **`for` e `id`** — O atributo `for` do label deve corresponder ao `id` do input. Isso permite que leitores de tela anunciem o label quando o campo recebe foco.

* **`aria-describedby`** — Conecta o campo a textos auxiliares (instrução e mensagem de erro). O leitor de tela anuncia esses textos após o label.

* **`aria-required`** — Indica programaticamente que o campo é obrigatório.

* **`inputmode="numeric"`** — Em dispositivos móveis, exibe o teclado numérico sem restringir a entrada.

---

## Navegação por teclado

Todo o fluxo de verificação de CPF deve ser operável apenas com teclado:

* **Tab** — Navega entre os elementos focáveis (campo, botão, link).

* **Enter** — Ativa botões e links.

* **Escape** — Fecha tooltips ou modais de ajuda.

### Ordem de foco lógica

A ordem de foco (tab order) deve seguir o fluxo visual:

1. Campo de CPF
2. Botão de verificar (se houver)
3. Área de resultados (após a consulta)

### Indicador de foco visível

Nunca remova o outline padrão do navegador sem oferecer uma alternativa:

```css
.campo-cpf input:focus {
 outline: 2px solid #3b82f6;
 outline-offset: 2px;
}

.campo-cpf input:focus:not(:focus-visible) {
 outline: none;
}

.campo-cpf input:focus-visible {
 outline: 2px solid #3b82f6;
 outline-offset: 2px;
}
```

---

## Comunicação de estados com leitores de tela

Leitores de tela (NVDA, JAWS, VoiceOver) precisam de informações programáticas sobre o que está acontecendo na interface. Para o fluxo de verificação de CPF, três estados devem ser comunicados:

### Estado de carregamento

Quando a API está processando a consulta:

```javascript
function iniciarCarregamento() {
 const mensagem = document.getElementById('cpf-mensagem');
 mensagem.textContent = 'Verificando CPF. Aguarde.';
 mensagem.setAttribute('role', 'status');
}
```

### Estado de sucesso

Quando a validação é concluída com sucesso:

```javascript
function exibirSucesso(nome) {
 const mensagem = document.getElementById('cpf-mensagem');
 mensagem.textContent = `CPF verificado com sucesso. Titular: ${nome}.`;
 mensagem.setAttribute('role', 'status');
}
```

### Estado de erro

Quando a validação falha:

```javascript
function exibirErro(textoErro) {
 const mensagem = document.getElementById('cpf-mensagem');
 mensagem.textContent = textoErro;
 mensagem.setAttribute('role', 'alert');

 // Mover foco para o campo com erro
 document.getElementById('cpf').focus();
 document.getElementById('cpf').setAttribute('aria-invalid', 'true');
}
```

O atributo `role="alert"` garante que o leitor de tela anuncie o erro imediatamente, sem que o usuário precise navegar até a mensagem.

---

## Implementação acessível com consulta à API

Veja um exemplo completo que integra acessibilidade com a consulta de CPF via [**CPFHub.io**](https://www.cpfhub.io/):

```javascript
async function verificarCPFAcessivel() {
 const campo = document.getElementById('cpf');
 const mensagem = document.getElementById('cpf-mensagem');
 const cpf = campo.value.replace(/\D/g, '');

 // Limpar estado anterior
 campo.removeAttribute('aria-invalid');
 mensagem.textContent = '';

 // Validação local
 if (cpf.length !== 11) {
 exibirErro('O CPF precisa ter 11 dígitos. Verifique e tente novamente.');
 return;
 }

 // Estado de carregamento
 iniciarCarregamento();

 try {
 const controller = new AbortController();
 const timeout = setTimeout(() => controller.abort(), 10000);

 const response = await fetch(
 `https://api.cpfhub.io/cpf/${cpf}`,
 {
 headers: {
 'x-api-key': 'SUA_CHAVE_DE_API',
 'Accept': 'application/json'
 },
 signal: controller.signal
 }
 );

 clearTimeout(timeout);
 const resultado = await response.json();

 if (resultado.success) {
 exibirSucesso(resultado.data.name);
 campo.setAttribute('aria-invalid', 'false');
 } else {
 exibirErro('CPF não encontrado. Verifique o número e tente novamente.');
 }
 } catch (erro) {
 exibirErro('A verificação falhou. Tente novamente em alguns instantes.');
 }
}
```

---

## Contraste e legibilidade visual

Para usuários com baixa visão, o contraste e o tamanho do texto são essenciais:

* **Tamanho mínimo do texto** — Labels e mensagens devem ter pelo menos 16px. Mensagens de erro, pelo menos 14px.

* **Contraste de cores** — Texto sobre fundo deve ter razão de contraste de pelo menos 4.5:1 para texto normal e 3:1 para texto grande.

* **Não depender apenas de cor** — Mensagens de erro não devem usar apenas a cor vermelha como indicador. Adicione ícones e texto descritivo.

* **Máscara legível** — Os pontos e o hífen da máscara de CPF devem ser visíveis. Fontes que confundem 0 com O ou 1 com l devem ser evitadas.

---

## Deficiência motora e áreas de toque

Para usuários com dificuldades motoras:

* **Área de toque mínima** — Botões e campos devem ter pelo menos 44×44 pixels de área clicável (WCAG 2.5.5).

* **Tolerância a cliques imprecisos** — Não coloque botões de "limpar campo" muito próximos ao campo de input.

* **Tempo suficiente** — Se a validação tem timeout, ofereça a opção de estender o tempo.

* **Sem gestos complexos** — Evite interações que exijam arrastar, deslizar ou gestos multitouch para o campo de CPF.

---

## Testando a acessibilidade do fluxo

### Testes automatizados

Ferramentas como axe, Lighthouse e WAVE identificam problemas de acessibilidade programáticos:

* Labels ausentes ou desassociados.
* Contraste insuficiente.
* Atributos ARIA incorretos.

### Testes manuais com teclado

Navegue por todo o fluxo usando apenas Tab, Enter e Escape. Verifique se:

* Todos os elementos são alcançáveis.
* A ordem de foco é lógica.
* O indicador de foco é visível.

### Testes com leitores de tela

Teste com pelo menos um leitor de tela (NVDA no Windows, VoiceOver no macOS/iOS) e verifique se:

* O label é anunciado ao focar no campo.
* A instrução auxiliar é anunciada.
* Mensagens de erro e sucesso são anunciadas automaticamente.

---

## Perguntas frequentes

### A Lei Brasileira de Inclusão exige que formulários digitais sejam acessíveis?

Sim. A Lei 13.146/2015 (LBI) determina que produtos e serviços digitais oferecidos ao público devem ser acessíveis a pessoas com deficiência. Para formulários web, isso significa seguir as diretrizes WCAG 2.1, nível AA, que incluem associação de labels, contraste mínimo de 4.5:1 e operabilidade completa via teclado. O descumprimento pode resultar em responsabilização civil e administrativa.

### Qual a diferença entre `role="alert"` e `role="status"` em mensagens de validação de CPF?

`role="alert"` é para mensagens urgentes que interrompem o leitor de tela imediatamente — ideal para erros de validação. `role="status"` é para mensagens informativas que o leitor de tela anuncia na próxima oportunidade — ideal para o estado "verificando CPF". Use `alert` quando o usuário precisa agir (erro) e `status` quando a interface apenas informa um progresso.

### O `inputmode="numeric"` restringe o campo a aceitar apenas números?

Não. O `inputmode="numeric"` instrui o navegador a exibir o teclado numérico em dispositivos móveis, mas não impede a entrada de outros caracteres. Para um campo de CPF, isso é o comportamento correto: o usuário pode digitar 000.000.000-00 com pontos e hífen no teclado físico, e o `inputmode` garante que no celular apareça o teclado numérico por padrão, facilitando a digitação dos onze dígitos.

### Como garantir que a mensagem de retorno da API de CPF seja anunciada por leitores de tela?

O elemento que recebe a mensagem precisa ter `aria-live="assertive"` ou `role="alert"` declarados no HTML antes da requisição ser feita. Se você inserir esses atributos dinamicamente via JavaScript após a resposta da API, muitos leitores de tela não detectarão a mudança. Declare o elemento no HTML com o atributo, deixe-o vazio e atualize apenas o `textContent` via JavaScript quando a resposta chegar.

### Leia também

- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [Como pedir CPF no checkout sem espantar o cliente](https://cpfhub.io/blog/como-pedir-cpf-no-checkout-sem-espantar-o-cliente)
- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)
- [Como validar CPF no frontend com React e API REST](https://cpfhub.io/blog/como-validar-cpf-no-frontend-com-react-e-api-rest)

---

## Conclusão

Criar um fluxo de verificação de CPF acessível beneficia todos os usuários, não apenas pessoas com deficiência. Labels claros, navegação por teclado, comunicação adequada de estados e contraste visual são práticas que melhoram a experiência de forma universal e reduzem abandonos no formulário.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e implemente verificação de CPF em tempo real com retorno de nome e data de nascimento, pronto para integrar a qualquer fluxo acessível.

