Boas práticas
Foco visível: porque é que «outline: none» quebra a acessibilidade por teclado
Se removermos o outline CSS por razões estéticas, tornamos o site inutilizável através do teclado. Esta prática comum viola dois critérios das WCAG em causa: o foco visível (2.4.7) e o foco não oculto (2.4.11). As soluções modernas, como :focus-visible e outline-offset, permitem um indicador discreto, contrastado e conforme.

A resposta curta
O indicador de foco (frequentemente um contorno cinzento ou azul) sinaliza que um elemento de formulário, uma ligação ou um botão está a receber interação através do teclado. Remover este contorno com *outline: none* sem o substituir torna a navegação por teclado invisível: uma limitação grave para qualquer utilizador que não possa usar o rato. O critério WCAG 2.4.7 exige-o; o 2.4.11 especifica que não deve ser ocultado.
O foco não serve apenas para mostrar que um elemento está selecionado. Permite também compreender onde nos encontramos no percurso da página, que ação será desencadeada com a tecla *Enter* e que campo receberá a próxima inserção. Sem referência visual, o utilizador tem de adivinhar a sua posição ou reiniciar a navegação desde o início.
A correção não consiste, portanto, em manter obrigatoriamente o estilo nativo do navegador. Consiste em garantir um indicador percetível, coerente e com contraste suficiente em cada componente interativo. Este indicador pode respeitar a identidade gráfica do sítio, desde que permaneça visível em todos os estados e sobre todos os fundos.
Porque é que « outline: none » se tornou um hábito
O contorno padrão dos navegadores é um retângulo cinzento ou azul bastante espesso, imposto desde os anos 1990 por razões de segurança no acesso. A partir dos anos 2010, os designers consideraram-no pouco estético: «quebraria» o design minimalista. Os resets de CSS (Normalize, Reset ou nativos do Bootstrap) começaram a ocultá-lo, muitas vezes sem substituição: «outline: none» propagou-se como padrão nos frameworks e nos ateliers de desenvolvimento.
O problema é sistémico: esta supressão é quase automática, raramente intencional. O estudo Inclaria 2026 mostra que, entre os 55 sites de comércio eletrónico franceses analisados, a maioria das não conformidades críticas inclui pelo menos uma supressão de outline sem substituição. É um sintoma: não há teste com teclado, nem revisão de acessibilidade a montante do design.
Outra causa frequente é a confusão entre o foco acionado por um clique e o acionado pelo teclado. As equipas pretendem remover o anel que aparece após um clique do rato, aplicando depois «outline: none» a todos os estados «:focus». Esta regra afeta então também as pessoas que utilizam Tab, Shift + Tab ou uma tecnologia de assistência. «:focus-visible» responde precisamente a este problema, distinguindo as modalidades de interação.
Quem está bloqueado?
Quatro perfis são diretamente afetados.
- Os utilizadores que dependem apenas do teclado: deficiência motora, tremores, paralisia ou tecnologia de assistência (pedal, rato adaptado). Não veem nada acontecer quando navegam no formulário com a tecla Tab.
- Os utilizadores que navegam com o teclado por preferência: programadores, analistas de dados, *power users* que poupam 15 segundos por formulário, cegos e pessoas com baixa visão que utilizam um leitor de ecrã (que se baseia frequentemente no foco visual do navegador ou num anel de leitor).
- Utilizadores idosos ou em situação de fadiga motora: a precisão com o rato torna-se difícil; o teclado é mais fácil e rápido.
- Situações de deficiência temporária: braço partido, *trackpad* avariado, trabalhar num monitor tátil sem rato.
O bloqueio pode ser total num formulário longo. Uma pessoa pode chegar ao botão de validação sem saber qual o controlo ativo, acionar involuntariamente uma ligação secundária ou alterar um campo já preenchido. Numa janela modal, a ausência de indicador pode também dar a impressão de que o teclado deixou de funcionar, quando, na realidade, o foco continua a deslocar-se para elementos invisíveis ou situados atrás da janela.
Os critérios WCAG em causa
Dois critérios colocam problemas:
| Critério | Exigência | Impacto de outline: none |
|---|---|---|
| WCAG 2.4.7: Foco visível | Qualquer elemento de formulário ou elemento interativo que possa receber o foco DEVE ter um indicador de foco visível. | outline: none sem substituição torna o indicador invisível: violação direta. |
| WCAG 2.4.11: Foco não oculto | O indicador de foco não deve ser ocultado por outros elementos da página (por exemplo, uma barra fixa, um menu overlay). | Um outline: none cumulado com outline-offset: -2px (ou negativo) oculta ainda mais a indicação. |
Ao nível da conformidade legal, estes dois critérios são de nível AA, obrigatórios em França ao abrigo da diretiva europeia (European Accessibility Act, aplicável a partir de 28 de junho de 2025 para os novos serviços, 28 de junho de 2030 para os serviços existentes).
A visibilidade deve ser verificada nas condições reais de utilização, não apenas num componente isolado numa biblioteca de design. Um anel conforme sobre fundo branco pode tornar-se impercetível numa faixa azul, ser cortado por overflow: hidden ou desaparecer sob um cabeçalho posicionado em fixed. A conformidade depende, portanto, do resultado final, da posição do elemento e do seu ambiente visual.
A solução moderna: :focus-visible e outline-offset
Os navegadores modernos e tecnologias de assistência suportam :focus-visible (desde 2018, o IE 11 não é suportado, mas requer uma estratégia degradada: .element:focus { outline: 2px solid #0066cc; } e depois .element:focus-visible { /* regras refinadas */ }).
A regra a reter: :focus-visible visa apenas o foco via teclado, não o foco via rato (em .element:focus-visible { … }). Isto permite manter a interface limpa ao clicar, ao mesmo tempo que mantém o teclado acessível.
Exemplo 1: substituir o outline padrão
a, button, input:focus-visible { outline: 2px solid #0066cc; outline-offset: 2px; }
Aqui, outline-offset: 2px cria um espaço entre o elemento e o anel, evitando ocultar o conteúdo (critério 2.4.11).
Para uma cobertura homogénea, a mesma lógica deve ser aplicada aos outros componentes interativos: áreas de texto, listas suspensas, controlos personalizados, elementos com tabindex e widgets JavaScript. Adicionar uma regra apenas aos links e botões deixa frequentemente lacunas no percurso do teclado.
Exemplo 2: outline cinzento contrastado, também para dark mode
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #333; outline-offset: 4px; } @media (prefers-color-scheme: dark) { a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #fff; } }
O contraste mínimo de 3:1 (ligação 1.4.11, tom de cinza) é respeitado: #333 sobre branco = 8,6:1 de contraste.
Exemplo 3: box-shadow como indicador
E se quiseres mesmo substituir o outline? O box-shadow também funciona, mas não cria um deslocamento como o outline-offset:
a:focus-visible { outline: none; box-shadow: 0 0 0 3px #0066cc; }
Atenção: o box-shadow consome um pouco mais de GPU do que o outline e não é desenhado fora dos contentores `overflow: hidden`. O outline é mais robusto.
Se outline: none continuar a ser necessário numa regra específica, a sua substituição deve ser definida no mesmo bloco ou numa regra imediatamente identificável. Esta proximidade limita o risco de uma futura modificação na cascata eliminar o indicador alternativo. Também é necessário testar os estados combinados, nomeadamente :hover, :active, :disabled e :focus-visible, para que um estilo mais específico não sobrescreva acidentalmente o foco.
Como testar se o foco é visível
- Pressionar a tecla Tab no teclado: cada elemento interativo (ligação, botão, campo de preenchimento) deve ter um anel visível à sua volta.
- Abrir as DevTools do navegador (F12), separador «Accessibility» (Chrome, Edge) ou «Inspector → Accessibility» (Firefox), e observar o indicador de foco ao navegar com a tecla Tab.
- Utilizar um leitor de ecrã (NVDA no Windows, VoiceOver no Mac/iOS): este anuncia o elemento em foco; o foco visual deve acompanhar simultaneamente.
O teste deve abranger toda a página nos dois sentidos, com Tab e depois Shift + Tab. A ordem de deslocação deve manter-se lógica, o indicador nunca deve desaparecer e nenhum elemento deve prender o teclado. É também necessário abrir menus, acordeões, janelas modais e componentes dinâmicos, pois o seu comportamento nem sempre é visível num simples percurso da página principal.
Teste, por fim, várias larguras de ecrã e níveis de zoom. A 200 %, um cabeçalho fixo ou um banner de consentimento pode sobrepor-se ao elemento focado, embora tudo pareça correto a 100 %. O foco deve permanecer pelo menos parcialmente visível quando o conteúdo se reorganiza.
Detecção de remoções de outline
O scanner Inclaria testa duas coisas: (1) a presença de um indicador de foco visível nos elementos-chave (formulários, botões, ligações); (2) o deslocamento desse indicador (sem ocultação sob um menu fixo, por exemplo). Uma supressão de «outline: none» sem substituição é assinalada como não conformidade com a WCAG 2.4.7.
O relatório prioriza esta falha: surge frequentemente em centenas de elementos (CSS reset aplicado em toda a parte) e tem um impacto directo na usabilidade.
Uma detecção automatizada permite identificar rapidamente as regras CSS suspeitas e os componentes sem estilo de substituição. No entanto, deve ser complementada por um teste manual com teclado, uma vez que a visibilidade real depende do contraste, do contexto gráfico, da rolagem e de eventuais elementos sobrepostos.
Perguntas frequentes
Devo manter absolutamente o outline padrão do navegador?
Não: podes adaptá-lo ao design, mas tens de o substituir, nunca o eliminar apenas. outline: 2px solid #0066cc; outline-offset: 2px; é discreto, profissional e conforme.
O que acontece se misturar :focus (rato) e :focus-visible (teclado)?
É a boa prática moderna. :focus aplica-se nos dois casos (rato + teclado), :focus-visible apenas no teclado. Podes ter .elemento:focus { /* nada */ } e .elemento:focus-visible { outline: 2px solid #0066cc; }, o que torna o rato discreto e o teclado acessível.
O contraste 3:1 do indicador aplica-se também sobre imagens?
Sim: o critério 1.4.11 diz que o indicador de foco deve ter um contraste de 3:1 em relação a todos os píxeis adjacentes. Se o teu outline passar sobre uma fotografia colorida, a cor do outline deve manter sempre 3:1 contra o fundo. box-shadow escuro ou outline branco/preto em todos os fundos é mais seguro.
Os meus utilizadores nunca navegam com o teclado. Posso ignorar :focus-visible?
Isso constitui uma violação legal a partir de junho de 2025 (EAA). É também uma má suposição: os testadores, os reguladores, as pessoas com deficiência motora e os utilizadores avançados fá-lo-ão. Uma fração dos teus utilizadores não o diz.
Como é que :focus-visible e :focus se sobrepõem no meu CSS reset?
Escreve: a { } depois a:focus { } (opcional: nada ou sombra ligeira) e depois a:focus-visible { outline: 2px solid #0066cc; outline-offset: 2px; }. O navegador aplica :focus primeiro, depois :focus-visible se for teclado: :focus-visible prevalece.
Pode-se usar border em vez de outline para o indicador de foco?
Sim, mas border desloca o elemento (box-sizing: border-box limita-o). outline não desloca nada: é uma vantagem. outline + outline-offset é o caminho mais seguro.
Definições relacionadas
Para ler a seguir
Comece com uma análise gratuita
Obtenha a sua pontuação de acessibilidade, os problemas prioritários e a declaração em falta em segundos.
Analisar o meu site