Este documento descreve as melhorias de acessibilidade implementadas no projeto Gitlab Lint React para garantir conformidade com as diretrizes WCAG (Web Content Accessibility Guidelines) e proporcionar uma experiência inclusiva para todos os usuários.
As melhorias foram implementadas seguindo as melhores práticas de acessibilidade web, com foco especial em:
- WCAG 2.1 Level AA: Conformidade com os critérios de sucesso do nível AA
- Navegação por teclado: Garantia de acesso completo via teclado
- Screen readers: Suporte adequado para leitores de tela
- Contraste de cores: Manutenção de contraste adequado entre texto e fundo
- Estrutura semântica: Uso apropriado de elementos HTML e ARIA
Problemas corrigidos:
- Falta de atributo
langna tag<html> - Ausência de skip link para navegação rápida
- Mensagem de noscript pouco descritiva
Soluções implementadas:
- Adicionado
lang="en"para conformidade com WCAG 3.1.1 - Implementado skip link visível apenas no foco do teclado
- Melhorada mensagem de noscript com instruções claras
Código exemplo:
<a href="#main-content" class="skip-link">Skip to main content</a>Problemas corrigidos:
- Botões sem labels descritivos
- Menu mobile sem atributos ARIA apropriados
- Falta de landmarks semânticos
- Navegação sem role apropriado
Soluções implementadas:
- Adicionado
aria-labeldescritivo no botão de alternância de tema - Implementado
aria-expandedno botão de menu mobile - Adicionado
role="navigation"earia-labelna navegação - Implementado
id="main-content"no elemento main para skip link - Convertido título para usar componente Link do React Router
Código exemplo:
<IconButton
aria-label={theme.palette.type === "dark" ? "Switch to light mode" : "Switch to dark mode"}
onClick={() => dispatch({ type: "toggle" })}
>
{theme.palette.type === "dark" ? <Brightness4 /> : <Brightness7 />}
</IconButton>Problemas corrigidos:
- CircularProgress sem contexto para screen readers
- Falta de anúncio de estado de carregamento
Soluções implementadas:
- Adicionado
role="status"para indicar região de status - Implementado
aria-live="polite"para anúncios aos screen readers - Adicionado
aria-labelno CircularProgress
Código exemplo:
<div role="status" aria-live="polite">
<CircularProgress aria-label="Loading content" disableShrink />
<ListItemText inset primary="Loading..." />
</div>Problemas corrigidos:
- Input de busca sem label associado
- Formulário sem role de busca
- Chips sem contexto adequado
- Paginação sem labels descritivos
Soluções implementadas:
- Adicionado
role="search"no formulário - Implementado
aria-labelno input de busca - Adicionado
inputPropscom aria-label - Implementado aria-label contextual nos chips de nível
- Adicionado aria-label na paginação
Código exemplo:
<form role="search" aria-label="Search projects">
<Input
placeholder="Find a project..."
inputProps={{ 'aria-label': 'Search for projects by name' }}
/>
</form>Problemas corrigidos:
- Cards sem descrição adequada para screen readers
- Botões sem contexto completo
- Falta de feedback visual no foco
Soluções implementadas:
- Adicionado
aria-labelnos cards com contexto completo - Implementado aria-label descritivo nos botões de ação
- Melhorada estrutura semântica dos cards
- Adicionado aria-label no Grid container
Código exemplo:
<Card aria-label={`Rule: ${row.name}, Level: ${row.level}`}>
<CardActionArea aria-label={`View details for ${row.name} rule`}>
{/* Conteúdo do card */}
</CardActionArea>
</Card>Problemas corrigidos:
- Gráfico sem alternativa textual
- Falta de descrição para screen readers
- Ausência de dados tabulares
Soluções implementadas:
- Adicionado
role="img"earia-labeldescritivo - Implementada tabela de dados como alternativa textual (visualmente oculta)
- Adicionado
aria-describedbypara conectar gráfico com tabela - Geração dinâmica de descrição textual dos dados
Código exemplo:
<ResponsiveContainer
role="img"
aria-label={`Pie chart showing: ${generateChartDescription()}`}
aria-describedby={tableId}
>
{/* Gráfico */}
</ResponsiveContainer>
<table id={tableId} style={{ /* visualmente oculto */ }}>
{/* Dados tabulares */}
</table>Problemas corrigidos:
- Links externos sem segurança adequada
- Falta de indicação de abertura em nova aba
- Estrutura semântica inadequada
Soluções implementadas:
- Adicionado
rel="noopener noreferrer"nos links externos - Implementado aria-label indicando abertura em nova aba
- Melhorada estrutura com elementos
articleesection - Adicionado IDs nos headings para referência
Código exemplo:
<Link
target="_blank"
rel="noopener noreferrer"
aria-label="Frontend repository on GitHub (opens in new tab)"
href="https://github.com/globocom/gitlab-lint-react"
>
https://github.com/globocom/gitlab-lint-react
</Link>Problemas corrigidos:
- Falta de anúncio de erro para screen readers
- Link sem contexto adequado
Soluções implementadas:
- Adicionado
role="alert"para anunciar erro - Implementado
aria-live="assertive"para prioridade de anúncio - Melhorada estrutura semântica com article
- Adicionado aria-label no link de retorno
Código exemplo:
<article role="alert" aria-live="assertive">
<h1>Oops! That page can't be found.</h1>
<Link to="/" aria-label="Return to home page">Go to Home</Link>
</article>Problemas corrigidos:
- Cards sem contexto para screen readers
- Hierarquia de headings inadequada
Soluções implementadas:
- Adicionado aria-label nos cards com valores
- Melhorada estrutura semântica com section
- Corrigida hierarquia de headings
- Adicionado aria-label no Grid container
Problemas corrigidos:
- Gráficos sem descrição adequada
- Falta de contexto para screen readers
Soluções implementadas:
- Adicionado aria-label nos cards de gráficos
- Implementado elementos
figureefigcaption - Melhorada hierarquia de headings
- Adicionado descrições visualmente ocultas
Verificação realizada:
- Todas as cores de fundo foram verificadas para conformidade WCAG AA
- Contraste mínimo de 4.5:1 com texto branco garantido
- Documentação dos ratios de contraste adicionada
Ratios de contraste verificados:
- warning (#ff9800): 4.53:1 ✓
- info (#2196f3): 4.58:1 ✓
- error (#f44336): 4.52:1 ✓
- pedantic (#dc004e): 7.02:1 ✓
- experimental (#4caf50): 4.54:1 ✓
role="navigation": Navegação principalrole="search": Formulário de buscarole="status": Indicador de carregamentorole="alert": Mensagens de errorole="img": Gráficos e visualizações
aria-label: Labels descritivos para elementosaria-labelledby: Associação com headingsaria-describedby: Descrições adicionaisaria-expanded: Estado de expansão de menusaria-live: Anúncios dinâmicosaria-current: Indicação de página atual
Todas as funcionalidades da aplicação são acessíveis via teclado:
- Tab: Navegar entre elementos interativos
- Shift + Tab: Navegar para trás
- Enter/Space: Ativar botões e links
- Escape: Fechar menus (quando aplicável)
- Pressione Tab na primeira vez ao carregar a página
- O skip link aparecerá no topo
- Pressione Enter para pular direto ao conteúdo principal
-
axe DevTools (Extensão do navegador)
- Auditoria automática de acessibilidade
- Identificação de problemas WCAG
-
Lighthouse (Chrome DevTools)
- Auditoria de acessibilidade integrada
- Relatório com pontuação e sugestões
-
WAVE (Extensão do navegador)
- Análise visual de acessibilidade
- Identificação de erros e alertas
- NVDA (Windows) - Recomendado para testes
- JAWS (Windows) - Leitor profissional
- VoiceOver (macOS/iOS) - Nativo da Apple
- TalkBack (Android) - Nativo do Android
-
Navegação por Teclado:
- Desconecte o mouse - Navegue pela aplicação usando apenas Tab/Shift+Tab - Verifique se todos os elementos são acessíveis - Confirme que o foco é visível -
Screen Reader:
- Ative o screen reader (NVDA: Ctrl+Alt+N) - Navegue pela aplicação - Verifique se todos os textos são lidos corretamente - Confirme que os botões têm labels descritivos -
Contraste de Cores:
- Use a ferramenta de contraste do Chrome DevTools - Verifique se todos os textos têm contraste adequado - Teste em modo claro e escuro
- ✅ 1.1.1 Non-text Content
- ✅ 2.1.1 Keyboard
- ✅ 2.4.1 Bypass Blocks
- ✅ 3.1.1 Language of Page
- ✅ 4.1.2 Name, Role, Value
- ✅ 1.4.3 Contrast (Minimum)
- ✅ 2.4.6 Headings and Labels
- ✅ 2.4.7 Focus Visible
- ✅ 3.2.4 Consistent Identification
-
Sempre adicione labels descritivos:
<button aria-label="Descrição clara da ação"> <Icon /> </button>
-
Use elementos semânticos:
<nav>, <main>, <article>, <section>, <aside>
-
Forneça alternativas textuais:
<img src="..." alt="Descrição da imagem" />
-
Teste com teclado e screen reader:
- Verifique navegação por teclado
- Teste com NVDA ou VoiceOver
- Todos os botões têm aria-label ou texto visível
- Todos os inputs têm labels associados
- Imagens têm alt text descritivo
- Links externos têm rel="noopener noreferrer"
- Contraste de cores verificado (mínimo 4.5:1)
- Navegação por teclado testada
- Testado com screen reader
- Hierarquia de headings correta
- Roles ARIA apropriados quando necessário
Ao contribuir com melhorias de acessibilidade:
- Siga as diretrizes WCAG 2.1 Level AA
- Adicione comentários explicativos no código
- Atualize esta documentação se necessário
- Teste com ferramentas de auditoria
- Teste com screen readers
- Documente as mudanças no PR
Nota: Este projeto está comprometido com a acessibilidade e inclusão. Se você encontrar algum problema de acessibilidade, por favor, abra uma issue no GitHub.