25 out 2026 · 3 min de leitura
Galeria de projetos acessível: teclado e leitores de ecrã
Cria uma galeria de projetos acessível: estilos de foco visíveis, filtros com aria-pressed e uma região aria-live discreta para leitores de ecrã.
Construir um portefólio implica mostrar os projetos com clareza, mas uma galeria que só funciona com o rato não está terminada. Neste artigo explico como fiz com que a galeria de projetos deste site funcione para quem usa apenas o teclado e leitores de ecrã, e os erros que tive de corrigir pelo caminho.
O que a galeria precisava de fazer
- Permitir chegar a cada cartão e filtro numa ordem de tabulação lógica.
- Mostrar sempre um indicador de foco claro.
- Avisar os utilizadores de leitores de ecrã quando um filtro altera a lista.
Estilos de foco que funcionam em qualquer configuração
A minha primeira versão usava focus:outline-none com um anel. É uma armadilha: remove o contorno de que o modo de cores forçadas do Windows depende, por isso o indicador de foco pode desaparecer por completo. Eis o que uso agora:
<button
class="focus-visible:outline focus-visible:outline-2 focus-visible:outline-transparent
focus-visible:ring-2 focus-visible:ring-sky-400 focus-visible:ring-offset-2
focus-visible:ring-offset-slate-950"
aria-pressed="true">
Todos os projetos
</button>
O contorno transparente é invisível normalmente, mas torna-se visível no modo de cores forçadas. Escolhi também as cores do anel e do desvio para o meu fundo escuro e verifiquei-as de acordo com o requisito de contraste de 3:1 das WCAG 2.2 para indicadores de foco. [Acrescenta o rácio de contraste que mediste.]
Botões de filtro e estado
Cada filtro é um botão de alternância que usa aria-pressed. “Todos os projetos” começa como true, e o meu script alterna os valores quando escolhes outra categoria. [Cola aqui a tua função de alternância.]
Os cartões ocultos têm de sair da ordem de tabulação
Quando um filtro oculta um cartão, este tem de ser removido da navegação por teclado, e não apenas esbatido. [Explica o que fazes: hidden, display: none ou inert.] Caso contrário, quem usa o teclado passa por cartões invisíveis, um dos erros mais comuns em galerias com filtros.
Anunciar alterações com uma região em direto
Quem vê o ecrã vê a grelha atualizar-se de imediato. Quem usa um leitor de ecrã não ouve nada se não o avisarmos. Adicionei uma região de estado vazia:
<div id="gallery-status" class="sr-only" role="status" aria-live="polite"></div>
Começa vazia de propósito, para que nada seja anunciado quando a página carrega. Depois atualizo-a a partir de JavaScript:
function updateLiveRegion(count, category) {
const el = document.getElementById('gallery-status');
el.textContent = '';
setTimeout(() => {
el.textContent = `A mostrar ${count} ${count === 1 ? 'projeto' : 'projetos'} em ${category}.`;
}, 100);
}
Dois detalhes importam. Limpar o texto primeiro e defini-lo depois de um breve atraso faz com que os leitores de ecrã o voltem a anunciar, mesmo que a mensagem seja igual à anterior. E polite deixa o leitor de ecrã acabar o que está a dizer em vez de se interromper.
Conclusões
Foco visível, atributos de estado corretos e uma região em direto discreta exigiram muito pouco código, mas mudaram o funcionamento da galeria para quem não usa rato. Se quiseres uma visão mais ampla, lê porque é que a acessibilidade web importa para todos.
Precisas de um site acessível? Começa um projeto.