1. Adicionar Alt Text em Imagens

Errado

<img src="logo.png">
<img src="chart.jpg" alt="">

Problema: Sem descrição ou alt vazio

Correto

<img src="logo.png" alt="Logo da Empresa XYZ">
<img src="chart.jpg" alt="Gráfico de vendas 2024: aumento de 25% em janeiro">

Bom: Alt descritivo e relevante

💡 Dica: Alt text deve descrever o que vê, não dizer "imagem de". Se imagem é puramente decorativa, use alt=""

2. Melhorar Contraste de Cores

Errado (1.2:1 - muito fraco)

.text { color: #cccccc; }

Texto cinza claro é ilegível

Correto (4.5:1+ - WCAG AA)

.text { color: #333333; }

Texto escuro tem contraste adequado

💡 Dica: Use verificador de contraste online para testar. Mire em 4.5:1 para texto normal, 3:1 para texto grande

Errado

<a href="/privacy">Clique aqui</a>
<a href="/docs">Leia mais</a>

Problema: Texto genérico sem contexto

Correto

<a href="/privacy">Leia nossa política de privacidade</a>
<a href="/docs">Documentação técnica completa</a>

Bom: Texto descreve destino

💡 Dica: Leitor de tela muitas vezes lê só os links. Seu texto deve fazer sentido isolado

4. Labels em Formulários

Errado

<input type="email" placeholder="Seu email">
<input type="password">

Problema: Sem label, leitor não sabe o que preencher

Correto

<label for="email">Email:</label>
<input type="email" id="email" name="email">

<label for="password">Senha:</label>
<input type="password" id="password" name="password">

Bom: Label clara associada com input

💡 Dica: Sempre use <label for="id"> com <input id="id">. Isso associa visualmente e no código

5. Indicador de Focus Visível

Errado

button:focus { outline: none; }

Problema: Remove indicador padrão, deixa vazio

Correto

button:focus {
  outline: 3px solid #0066cc;
  outline-offset: 2px;
}

/* Ou customizar */
button:focus {
  border: 2px solid #0066cc;
  background: #e6f2ff;
}

Bom: Focus é claro e visível

💡 Dica: Nunca remova outline sem substituir por algo visível. Usuários de teclado precisam saber onde estão

6. Estrutura de Headings

Errado

<h1>Bem-vindo</h1>
<h3>Seção Principal</h3> <!-- Pula H2 -->
<h3>Outra Seção</h3>
<h1>Rodapé</h1> <!-- Múltiplos H1 -->

Problema: Ordem confusa, estrutura quebrada

Correto

<h1>Bem-vindo</h1>

<h2>Seção Principal</h2>
<h3>Subsecção</h3>

<h2>Outra Seção</h2>

<footer>
  <h2>Recursos</h2> <!-- Footer tem seu próprio H2 -->
</footer>

Bom: Hierarquia clara e lógica

💡 Dica: Uma página = um H1. Headings devem descer na ordem (H1 → H2 → H3). Nunca pule níveis

7. Botões Semanticamente Corretos

Errado

<div onclick="submit()">Enviar</div>
<span onclick="openMenu()">Menu</span>

Problema: Não é semântico, não funciona com teclado

Correto

<button onclick="submit()">Enviar</button>
<button onclick="openMenu()" aria-expanded="false">Menu</button>

/* Ou com role se must usar DIV */
<div role="button" tabindex="0" onclick="submit()" onkeydown="if(event.key==='Enter') submit()">Enviar</div>

Bom: Usa <button> ou role="button" com handlers

💡 Dica: Use <button> sempre que possível. Se deve ser DIV, adicione role="button", tabindex="0" e trata Enter/Space

8. Validação de Formulários Acessível

Errado

<input type="email">
<span class="error" style="display:none;">Email inválido</span>

Problema: Erro não é anunciado, só visível

Correto

<label for="email">Email:</label>
<input type="email" id="email" aria-describedby="email-error">
<span id="email-error" role="alert" style="color:red;">Email inválido</span>

Bom: role="alert" anuncia erro, aria-describedby conecta

💡 Dica: Use role="alert" para mensagens de erro, e aria-describedby para conectar campo com mensagem

9. Iframes com Título

Errado

<iframe src="video.html"></iframe>
<iframe src="map.html" title=""></iframe>

Problema: Sem descrição, leitor não sabe o que é

Correto

<iframe src="video.html" title="Vídeo: Como Usar o Plugin"></iframe>
<iframe src="map.html" title="Mapa de localização da empresa"></iframe>

Bom: Title descreve conteúdo do iframe

💡 Dica: Todo iframe DEVE ter title. Use aria-label como alternativa

10. Vídeos com Legendas

Errado

<video src="tutorial.mp4"></video>

Problema: Usuários surdos não podem seguir

Correto

<video controls>
  <source src="tutorial.mp4" type="video/mp4">
  <track kind="captions" src="tutorial.vtt" srclang="pt" label="Português">
  Seu navegador não suporta vídeo
</video>

Bom: Legendas em arquivo VTT

💡 Dica: Use formato WebVTT para legendas. Ferramenta como Amara.org pode ajudar criar legendas

⚠️ Teste Experimental: Este teste está em fase experimental no plugin e não impacta o score até o momento. É considerado uma funcionalidade extra que melhora significativamente a experiência do usuário.

WCAG 2.4.1 - Bypass Blocks (Nível A)

Skip links (links de atalho) permitem que usuários de teclado e leitores de tela pulem blocos repetitivos de conteúdo (como menus de navegação) e cheguem direto ao conteúdo principal. Isso economiza tempo e melhora drasticamente a experiência de navegação.

❌ Sem Skip Links

<body>
  <nav>
    <!-- 50+ links de menu -->
  </nav>
  <main>
    <h1>Conteúdo Principal</h1>
  </main>
</body>

Problema: Usuário de teclado precisa apertar TAB 50+ vezes para chegar ao conteúdo

✅ Com Skip Links

<body>
  <!-- Links de atalho no topo da página -->
  <div class="skip-links">
    <a href="#main-content">Pular para o conteúdo</a>
    <a href="#navigation">Pular para o menu</a>
    <a href="#footer">Pular para o rodapé</a>
  </div>

  <nav id="navigation">
    <!-- 50+ links de menu -->
  </nav>

  <main id="main-content">
    <h1>Conteúdo Principal</h1>
  </main>

  <footer id="footer">
    <!-- rodapé -->
  </footer>
</body>

Bom: Usuário aperta TAB uma vez e vai direto ao conteúdo principal

CSS para Esconder Visualmente (mas manter acessível)

Os skip links devem ficar visualmente escondidos até receberem foco via teclado:

.skip-links {
  position: relative;
}

.skip-links a {
  /* Esconde visualmente mas mantém acessível */
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  
  /* Alternativa moderna (recomendada) */
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-links a:focus {
  /* Torna visível quando recebe foco */
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
  
  /* Estilo visual do link */
  display: inline-block;
  padding: 10px 20px;
  background: #000;
  color: #fff;
  text-decoration: none;
  font-weight: bold;
  z-index: 9999;
}

💡 Dicas Importantes:

  • Posicionamento: Coloque os skip links como primeiro elemento do <body>
  • Âncoras comuns: #main-content, #navigation, #footer, #search
  • Textos claros: Use "Pular para o conteúdo" em vez de apenas "Pular"
  • IDs obrigatórios: Certifique-se que os alvos (targets) existem com IDs correspondentes
  • Teste com teclado: Aperte TAB logo ao carregar a página - o primeiro link deve aparecer
  • Alternativa: Se usar tag <main> corretamente, alguns leitores já pulam automaticamente, mas skip links ainda são recomendados

🔬 Como o Plugin Detecta:

O teste experimental do plugin verifica:

  • ✓ Presença de links âncora no início da página
  • ✓ Padrões de href (#main-content, #navigation, etc.)
  • ✓ Textos descritivos em português, inglês, espanhol e francês
  • ✓ Técnicas de esconder visualmente (clip, clip-path, position)
  • ✓ Se os alvos (targets) existem no DOM
  • ✓ Presença de tag <main> como alternativa

O plugin fornece um percentual de confiança da detecção e recomendações específicas.

Próximos Passos

  1. Abra seu site e execute plugin
  2. Identifique o erro (ex: "Image without alt")
  3. Encontre a seção correspondente aqui (ex: #imagens)
  4. Copie o código correto
  5. Aplique no seu projeto
  6. Teste novamente com plugin