♿ Acessibilidade e Inclusão
🎯 Princípios Fundamentais
WCAG 2.1 - 4 Pilares da Acessibilidade
1. PERCEPTÍVEL
👁️ Informação e elementos da UI devem ser apresentados de forma que usuários possam percebê-los
👁️ Informação e elementos da UI devem ser apresentados de forma que usuários possam percebê-los
2. OPERÁVEL
⌨️ Componentes da UI e navegação devem ser operáveis por todos
⌨️ Componentes da UI e navegação devem ser operáveis por todos
3. COMPREENSÍVEL
🧠 Informação e operação da UI devem ser compreensíveis
🧠 Informação e operação da UI devem ser compreensíveis
4. ROBUSTO
🔧 Conteúdo deve ser robusto o suficiente para diferentes tecnologias
🔧 Conteúdo deve ser robusto o suficiente para diferentes tecnologias
<!-- Estrutura semântica básica -->
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Título Descritivo da Página</title>
</head>
<body>
<header role="banner">
<nav role="navigation" aria-label="Menu principal">
<!-- navegação -->
</nav>
</header>
<main role="main">
<!-- conteúdo principal -->
</main>
<aside role="complementary">
<!-- conteúdo relacionado -->
</aside>
<footer role="contentinfo">
<!-- informações da página -->
</footer>
</body>
</html>
🏗️ HTML Semântico
<header> - Cabeçalho
Contém informações introdutórias ou elementos de navegação
<header>
<h1>Nome do Site</h1>
<nav>...</nav>
</header>
<nav> - Navegação
Seção de links de navegação principais
<nav aria-label="Menu principal">
<ul>
<li><a href="#home">Início</a></li>
<li><a href="#sobre">Sobre</a></li>
</ul>
</nav>
<main> - Conteúdo Principal
Conteúdo principal único da página (apenas um por página)
<main>
<article>
<h1>Artigo Principal</h1>
<!-- conteúdo -->
</article>
</main>
<section> vs <article> vs <aside>
Diferentes tipos de agrupamento de conteúdo
<section><!-- Seção temática -->
<h2>Capítulo 1</h2>
<p>Conteúdo da seção...</p>
</section>
<article><!-- Conteúdo independente -->
<h2>Post do Blog</h2>
<p>Artigo completo...</p>
</article>
<aside><!-- Conteúdo relacionado -->
<h3>Leia também</h3>
<!-- links relacionados -->
</aside>
🎯 Benefícios do HTML semântico: Leitores de tela navegam facilmente, SEO melhorado, código mais limpo e manutenível.
🎭 Atributos ARIA
aria-label
Fornece nome acessível para elemento
<button aria-label="Fechar janela">
<span aria-hidden="true">×</span>
</button>
<input type="search"
aria-label="Buscar produtos">
aria-describedby
Referencia descrição adicional
<input type="password"
aria-describedby="senha-ajuda">
<div id="senha-ajuda">
Mínimo 8 caracteres
</div>
aria-expanded
Indica se elemento está expandido
<button aria-expanded="false"
aria-controls="menu">
Menu
</button>
<ul id="menu" hidden>
<li>Item 1</li>
</ul>
aria-live
Anuncia mudanças dinâmicas
<div aria-live="polite"
id="status"></div>
<div aria-live="assertive"
id="erro"></div>
<!-- polite: anuncia quando conveniente
assertive: anuncia imediatamente -->
role
Define função do elemento
<div role="button"
tabindex="0">
Botão customizado
</div>
<div role="alert">
Erro: preencha o campo
</div>
aria-hidden
Esconde elemento de leitores de tela
<span aria-hidden="true">🎉</span>
Parabéns!
<img src="decorativo.jpg"
alt=""
aria-hidden="true">
⚠️ Primeira regra do ARIA: Não use ARIA se existe elemento HTML nativo que faz a mesma coisa. Use <button> em vez de <div role="button">.
⌨️ Navegação por Teclado
<!-- Elementos naturalmente focáveis -->
<a href="#">Link</a>
<button>Botão</button>
<input type="text">
<textarea></textarea>
<select></select>
<!-- Tornando elemento focável -->
<div tabindex="0" role="button">
Div focável
</div>
<!-- Removendo do tab order -->
<button tabindex="-1">
Não focável por tab
</button>
<!-- CSS para indicação visual de foco -->
<style>
.elemento:focus {
outline: 3px solid #0066cc;
outline-offset: 2px;
}
/* Nunca remova outline sem alternativa! */
.botao:focus {
outline: none; /* ❌ RUIM */
box-shadow: 0 0 0 3px #0066cc; /* ✅ BOM */
}
</style>
💡 Teclas importantes:
• Tab: próximo elemento
• Shift+Tab: elemento anterior
• Enter: ativar link/botão
• Espaço: ativar botão
• Setas: navegação em grupos (radio, menu)
• Esc: fechar modal/menu
• Tab: próximo elemento
• Shift+Tab: elemento anterior
• Enter: ativar link/botão
• Espaço: ativar botão
• Setas: navegação em grupos (radio, menu)
• Esc: fechar modal/menu
🎨 Contraste e Cores
✅ Contraste Bom
Preto no branco
Razão: 21:1
Preto no branco
Razão: 21:1
⚠️ Contraste Médio
Cinza escuro no branco
Razão: 6.5:1
Cinza escuro no branco
Razão: 6.5:1
❌ Contraste Ruim
Cinza claro no cinza
Razão: 1.8:1
Cinza claro no cinza
Razão: 1.8:1
<!-- ✅ Boas práticas de cor -->
<!-- Use além da cor para transmitir informação -->
<span class="erro">❌ Campo obrigatório</span>
<span class="sucesso">✅ Salvo com sucesso</span>
<!-- Contraste mínimo (WCAG AA) -->
<!-- Texto normal: 4.5:1 -->
<!-- Texto grande (18pt+): 3:1 -->
<!-- Elementos gráficos: 3:1 -->
<style>
/* ✅ Contraste adequado */
.texto-normal {
color: #333; /* em fundo #fff - 12.6:1 */
}
.texto-grande {
color: #666; /* em fundo #fff - 5.7:1 */
font-size: 18pt;
}
/* ❌ Contraste insuficiente */
.texto-ruim {
color: #ccc; /* em fundo #fff - 1.6:1 */
}
</style>
⚠️ Ferramentas para testar contraste:
• WebAIM Contrast Checker
• Colour Contrast Analyser
• DevTools do Chrome (Lighthouse)
• Stark (plugin Figma/Sketch)
• WebAIM Contrast Checker
• Colour Contrast Analyser
• DevTools do Chrome (Lighthouse)
• Stark (plugin Figma/Sketch)
📝 Formulário Acessível Completo
✅ Este formulário implementa:
• Labels associados (for + id)
• Fieldsets para agrupamento
• Descrições com aria-describedby
• Mensagens de erro com role="alert"
• Status dinâmico com aria-live
• Autocomplete para facilitar preenchimento
• Labels associados (for + id)
• Fieldsets para agrupamento
• Descrições com aria-describedby
• Mensagens de erro com role="alert"
• Status dinâmico com aria-live
• Autocomplete para facilitar preenchimento
🧪 Testando Acessibilidade
🤖 Testes Automatizados
- Lighthouse (Chrome DevTools)
- axe DevTools
- WAVE (Web Accessibility Evaluation Tool)
- Pa11y (linha de comando)
👥 Testes Manuais
- Navegação apenas por teclado
- Leitores de tela (NVDA, JAWS, VoiceOver)
- Zoom até 200%
- Verificação de contraste
📱 Testes Mobile
- TalkBack (Android)
- VoiceOver (iOS)
- Switch Control
- Voice Control
<!-- Checklist básico de acessibilidade -->
✅ HTML semântico (header, nav, main, footer)
✅ Hierarquia de títulos (h1 → h2 → h3)
✅ Alt text em imagens informativas
✅ Labels em campos de formulário
✅ Contraste mínimo 4.5:1
✅ Navegação por teclado funcional
✅ Focus visível em elementos interativos
✅ Linguagem definida (lang="pt-BR")
✅ Títulos de página descritivos
✅ Links com texto compreensível
✅ Erro e sucesso claramente indicados
✅ Conteúdo estruturado logicamente
✨ Exemplo Prático Completo
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Acessível - Dicas de Tecnologia</title>
<style>
/* Reset básico */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Skip link */
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: #000;
color: #fff;
padding: 8px;
z-index: 1000;
text-decoration: none;
}
.skip-link:focus {
top: 0;
}
/* Focus visível */
a:focus,
button:focus,
input:focus,
textarea:focus {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
/* Cores com contraste adequado */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333; /* 12.6:1 contraste */
background: #fff;
}
.erro {
color: #d32f2f; /* 7.2:1 contraste */
}
.sucesso {
color: #2e7d32; /* 7.4:1 contraste */
}
</style>
</head>
<body>
<!-- Skip link para usuários de teclado -->
<a href="#main" class="skip-link">
Pular para o conteúdo principal
</a>
<header role="banner">
<h1>Blog Acessível</h1>
<nav role="navigation" aria-label="Navegação principal">
<ul>
<li><a href="#home">Início</a></li>
<li><a href="#artigos">Artigos</a></li>
<li><a href="#sobre">Sobre</a></li>
<li><a href="#contato">Contato</a></li>
</ul>
</nav>
</header>
<main id="main" role="main">
<article>
<header>
<h2>Como tornar seu site acessível</h2>
<p>
<time datetime="2024-01-15">15 de janeiro de 2024</time>
por <span>João Silva</span>
</p>
</header>
<section>
<h3>Introdução</h3>
<p>Acessibilidade web é essencial...</p>
<figure>
<img src="acessibilidade.jpg"
alt="Pessoa usando leitor de tela para navegar em um site">
<figcaption>
Tecnologias assistivas ajudam milhões de pessoas
</figcaption>
</figure>
</section>
<section>
<h3>Dicas práticas</h3>
<ol>
<li>Use HTML semântico</li>
<li>Teste com leitores de tela</li>
<li>Verifique contraste de cores</li>
</ol>
</section>
</article>
<section aria-label="Comentários">
<h2>Comentários (3)</h2>
<form method="POST">
<fieldset>
<legend>Deixe seu comentário</legend>
<label for="nome">Nome *</label>
<input type="text" id="nome" name="nome" required>
<label for="comentario">Comentário *</label>
<textarea id="comentario" name="comentario"
rows="4" required></textarea>
<button type="submit">Enviar Comentário</button>
</fieldset>
</form>
</section>
</main>
<aside role="complementary">
<h2>Artigos relacionados</h2>
<ul>
<li><a href="#">WCAG 2.1 explicado</a></li>
<li><a href="#">Testes com NVDA</a></li>
</ul>
</aside>
<footer role="contentinfo">
<p>© 2024 Blog Acessível. Todos os direitos reservados.</p>
<nav aria-label="Links do rodapé">
<a href="#">Política de Privacidade</a>
<a href="#">Termos de Uso</a>
</nav>
</footer>
</body>
</html>