Escrevendo JavaScript com acessibilidade em mente
Introdução
No meu primeiro post Writing HTML With Accessibility in Mind, expliquei por que e como comecei a me preocupar com acessibilidade na web. Também compartilhei algumas dicas sobre como você pode melhorar sua marcação para tornar seus sites mais acessíveis. Algumas daquelas dicas eram bem básicas, mas valiosas. Tudo se resume a duas das mais importantes regras não escritas no desenvolvimento frontend: Aprenda o básico e reserve o tempo que for necessário para planejar e escrever HTML. Você e seus usuários se beneficiarão com uma marcação limpa e semântica.
Felizmente, a HTML não é a única linguagem que temos para criar websites, mas quanto mais complexa a linguagem, mais facilmente as coisas podem dar errado e as coisas com JavaScript podem ficar muito complexas. Apesar de estarmos contente com o funcionamento do nosso código, é fácil esquecer os usuários com dispositivos de entrada que não seja um mouse ou um touch pad, por exemplo: usuários de teclado ou de leitor de tela. Neste segundo artigo sobre acessibilidade na Web, reuni algumas dicas sobre o que considerar ao escrever JavaScript e como tornar seus componentes JavaScript mais acessíveis.
JavaScript não é seu inimigo
Antes de ler minhas dicas, quero salientar uma coisa importante: criar um site acessível não significa que você tenha que decidir entre usar JavaScript ou não. Acessibilidade consiste em disponibilizar o conteúdo para o maior número de pessoas possível, o que também inclui usuários com navegadores e computadores antigos, conexões de internet lentas, restrições rígidas de segurança ( por exemplo, sem JavaScript ) e assim por diante. A experiência em condições como essas, nas quais a JavaScript poderá não funcionar ou levar muito tempo para ser carregada, pode não ser ideal, mas ainda é boa o suficiente se o site for acessível e utilizável.
Se a JavaScript for executável, ela poderá ser usada para melhorar a acessibilidade. Sara Soueidan escreveu sobre suas experiências com a criação de um widget para tooltip em “Construir um tooltip totalmente acessível… é mais difícil do que eu imaginava”. Ela explica como cada alternativa sem uso de JavaScript impactava negativamente a experiência do usuário“ e por que a JavaScript é importante para acessibilidade.
Marco Zehe escreveu sobre JavaScript e acessibilidade em JavaScript não é inimiga da acessibilidade!. Eu sugiro que você leia o post dele.
Chega de "papo", vamos à matéria. Divirta-se!
Um ótimo gerenciamento do foco é essencial
É importante garantir que nossos sites sejam navegáveis pelo teclado. Muitos usuários dependem do teclado quando navegam na web. Entre eles estão pessoas com deficiência motora, pessoas cegas e pessoas que não têm mãos ou não podem usar um mouse ou trackpad por qualquer motivo.
Navegar em um site via teclado significa saltar de um elemento focável para outro na ordem que eles aparecem no DOM. Isso geralmente é realizado usando a tecla Tab
ou Shift + Tab
para a direção inversa. Elementos focáveis são, entre outros, links, botões e elementos de formulário. Eles podem ser selecionados com a tecla Enter
e, por vezes, com a tecla Spacebar
. Por ser focável e selecionável de maneiras diferentes, eles vêm com funcionalidades padrão muito úteis. Portanto, faz sentido usar elementos semânticos corretos e escrever HTML em uma ordem lógica.
Elementos como <p>
, <h2>
e <div>
não podem receber o foco por padrão. Geralmente, usamos elementos como estes (não focáveis) para criar componentes personalizados com tecnologia JavaScript, o que pode ser problemático para usuários de teclado.
Tornando os elementos não focáveis em focáveis
É possível tornar os elementos que não recebem o foco por padrão em elementos facáveis declarando o atributo tabindex
com um valor inteiro. Se o valor for definido em 0 (zero) o elemento torna-se focável e acessível através do teclado.
Se o valor for um número negativo, o elemento pode receber o foco (por exemplo, com JavaScript), mas não pode ser acessado via teclado. Você também pode usar um valor maior que 0 (zero), mas isso altera a ordem de tabulação natural e é considerado um antipadrão.
HTML
<h2 tabindex="0"> Um cabeçalho focável</ h2>
Se você quiser saber mais sobre tabindex
, assista ao episódio de A11ycasts, Controlling focus with tabindex, de Rob Dodson.
Focando elementos com JavaScript
Mesmo que os elementos sejam focáveis, às vezes eles não estão na ordem correta no DOM. Para ilustrar, criei um componente simples tipo janela modal com HTML, CSS e JS ( Ver Pen ).
Se você usar a tecla Tab
para pular para o botão e pressionar Enter
, uma janela modal será exibida. Se você pressionar a tecla Tab
novamente, o foco saltará para o próximo link abaixo da janela modal. O comportamento esperado seria que o próximo elemento focalizado estivesse dentro da janela modal. Mas, não é, porque os elementos são focados na ordem em que aparecem no DOM e a janela modal está localizada na parte inferior do documento. Você pode ver isso em ação na seguinte gravação da tela.
Para consertar isso, você deve tornar a janela modal focável e, em seguida, focar com JavaScript.
HTML
<!-- Adicionar tabindex="0" -->
<div class="modal" id="modal2" tabindex="0">
...
</div>
JavaScript
// Use o método focus() para definir a
função de foco showModal() {
...
var modal=document.getElementById('modal2');
modal.focus();
...
}
Você pode ver isso em ação no exemplo atualizado em relação ao exemplo anterior ( ver Pen ) tabulando o botão, pressionando Enter
e tabulando novamente. Você verá que a janela modal agora recebe o foco.
Isso é ótimo, mas ainda há duas questões aqui.
Se você fechar a janela modal pressionando Esc
o foco será perdido. Idealmente, o foco deveria voltar para o botão onde estava antes de você abrir a janela modal. Para conseguir isso você tem que armazenar o último elemento focado em uma variável.
document.activeElement
retorna o elemento atual em foco.
JavaScript
// Variável para armazenar o último elemento focado
var lastFocusedElement;
function showModal () {
...
// Armazena o último elemento focado
lastFocusedElement=document.activeElement;
var modal=document.getElementById (modalID);
modal.focus ();
...
}
Agora que você tem uma referência ao botão, você pode focar novamente quando a janela modal estiver fechada.
JavaScript
function removeModal () {
...
// Retorna o foco para o último elemento focalizado
lastFocusedElement.focus ();
...
}
Eu atualizei o código em outra Pen ( ver Pen ). A acessibilidade é muito melhor agora, mas ainda há espaço para melhorias.
É aconselhável manter o foco dentro da janela modal quando ela é aberta. Até isso isso ainda não foi projetado.
Eu não vou entrar em detalhes, mas eu fiz uma quarta Pen com uma técnica denominada keyboard trap ( ver Pen ). Agora o foco permanece na janela modal enquanto ela estiver ativa.
Se você comparar a primeira e a última Pen, verá que não há muito código extra. Provavelmente não é uma solução perfeita, mas certamente é muito melhor de se usar.
Há outro exemplo para um modal acessível e um ótimo artigo chamado Como usar tabindex escrito por desenvolvedores do Google.
Se você quiser saber mais sobre testes de teclado, visite o site WebAIM. Eles fornecem uma lista das interações online mais comuns, os pressionamentos de tecla padrão para a interação e informações adicionais sobre as coisas a serem consideradas durante o teste. Para mais exemplos de gerenciamento de foco, confira o vídeo egghead.io Gerenciamento de foco usando CSS, HTML e JavaScript de Marcy Sutton ou o episódio da A11ycasts "What is Focus?", de Rob Dodson .
Se você precisar de um botão, use o elemento <button>
Eu já escrevi sobre botões no primeiro artigo, mas aparentemente muitas pessoas usam elementos genéricos como botões. Então, acho que não faz mal escrever mais sobre esse assunto.
Eu fiz uma Pen ( ver Pen ) para ilustrar alguns dos problemas de se usar os elementos span
ou div
como um botão em lugar de se usar os elementos button
ou input
. Se você percorrer a página criada na Pen, perceberá que pode focar o primeiro botão, mas não o segundo. A razão para isso é - claro - que o primeiro botão foi criado com uso do elemento button
e o segundo foi criado com uso do elemento div
. Você pode contornar esse problema declarando tabindex="0"
para o div
, que torna um elemento inicialmente não focável em focável. É por isso que o terceiro e o quarto botões são focáveis, ainda que tenham criados com uso do elemento div
.
HTML
<!-- Button focável -->
<button class="btn">Eu sou um botão</ button>
<!-- Div não focável -->
<div class="btn">Sou div</div>
<!-- Ainda é apenas um div, mas focável -->
<div class="btn" tabindex="0">Sou div</div>
<!-- Função de botão e focável -->
<div class="btn" tabindex="0" role="botão">Sou div</div>
O botão de div foi tornado focável mas ainda se comporta como um div
, mesmo se você declarar um role
de button
. Para ilustrar isso, adicionei um manipulador de eventos de clique simples a todos os elementos .btn
na Pen. Se você clicar nos botões, uma caixa de alerta será exibida, mas se você tentar fazer o mesmo usando as teclas ( Enter
ou Spacebar
), somente o primeiro botão acionará o evento. Você teria que adicionar um manipulador de eventos via teclado aos div-buttons para imitar totalmente o comportamento padrão dos botões, o que parece ser uma sobrecarga desnecessária, não é? É por isso que você deve usar o elemento <button>
se precisar de um botão.
Assista ao episódio de A11y casts “Apenas use o botão“ de Rob Dodson ou leia Links, Botões, Submissões e Divs, Oh Hell de Adrian Roselli para mais detalhes e exemplos.
Os usuários de leitores de tela devem ser informados quando o conteúdo muda dinamicamente
Normalmente, os leitores de tela só anunciam conteúdo quando um elemento é focado ou o usuário usa os comandos de navegação do seu próprio leitor de tela. Se o conteúdo for carregado dinamicamente e inserido no DOM, apenas os usuários com visão estarão cientes das alterações. ARIA Live Regions fornecem várias opções para contornar esse problema. Eu vou te mostrar como, em um exemplo.
Digamos que você tenha uma página de configurações de perfil onde possa editar dados pessoais e salvá-los. Quando o botão Salvar é clicado, as alterações são salvas sem recarregar a página. Um alerta informa ao usuário se as alterações foram bem-sucedidas ou não. Isso pode acontecer imediatamente ou levar algum tempo. Eu gravei um vídeo rápido para mostrar o que acabei de explicar.
Você pode ver que a ação foi bem sucedida, mas você não pode ouví-la. Os usuários de leitores de tela não notarão a alteração, mas há uma solução simples para esse problema. Ao declarar role
status
ou alert
para a caixa de mensagem, os leitores de tela ouvirão atualizações de conteúdo nesse elemento.
HTML
<div class="message" role="status">Changes saved!</div>
Se o texto da mensagem mudar, o novo texto será lido. Você pode ver e ouvir isso em ação neste vídeo e dar uma olhada no código nesta Pen
Seja educado com seus usuários
A diferença entre status
e alert
é que um alert
interromperá o leitor de tela se estiver no curso de anunciar algo diferente e status
irá aguardar até o leitor de tela terminar de anunciar.
Existe outro atributo chamado aria-live
, que admite três valores possíveis off
, polite
ou assertive
. off
é o valor padrão, aria-live="polite"
é equivalente a role="status"
e aria-live="assertive"
a role="alert"
. Em alguns “casos predefinidos bem conhecidos, é melhor usar um 'papel específico da live region' ”. Além disso, se um navegador não suportar, você poderá tentar usar os dois atributos. Léonie Watson compartilhou alguns resultados de testes em Suporte do leitor de tela para ARIA Live Regions.
HTML
<div role="alert" aria-live="assertive"> </div>
Às vezes, faz sentido anunciar mais do que apenas o conteúdo que mudou
Por padrão, os leitores de tela só apresentam conteúdo alterado, mesmo que haja outro conteúdo dentro da mesma região ativa, mas ocasionalmente faz sentido anunciar todo o texto.
É possível alterar o comportamento padrão com o atributo aria-atomic
. Se você configurá-lo para true
, as tecnologias assistivas apresentarão todo o conteúdo do elemento.
Há uma teste demonstração de aria-atomic por Paul J. Adam que compara diferentes configurações de Live Regions. Ele também testou sua demonstração com o VoiceOver no iOS 8.1 e gravou para que você possa vê-lo em ação. Eu sugiro que você assista a gravação ( VoiceOver iOS 8.1 Speaking Characters Remaining aria-atomic & aria-relevant on aria-live regions ) se você quiser entender melhor os possíveis casos de uso aria-atomic
.
Algumas coisas a considerar
- As Live Regions não movem o foco, apenas acionam o anúncio do texto.
- Use
alert
apenas para mudanças críticas.status
é melhor na maioria dos casos, porque é politer. - Evite criar alertas que desapareçam automaticamente porque podem desaparecer muito rapidamente.
- Durante meus testes, tive problemas com o VoiceOver. Ocultar o alerta usando CSS ou criá-lo dinamicamente não funcionou o tempo todo. Certifique-se de testar suas Live Regions completamente em diferentes navegadores com diferentes softwares.
Claro, há um episódio de A11ycasts "Alertas!" por Rob Dodson para mais detalhes e exemplos. Heydon Pickering tem outro exemplo para Live Regions em sua coleção de exemplos ARIA.
Você não precisa adivinhar quais padrões de uso seus widgets devem fornecer
Muitas vezes, é difícil pensar em todos os recursos que um widget deve fornecer em termos de navegação e acessibilidade. Felizmente, existe um recurso chamado WAI-ARIA Authoring Practices 1.1 que nos ajuda com isso. Práticas de Autoria WAI-ARIA é um guia para entender como usar o WAI-ARIA para criar um Aplicativo Rich Internet acessível. Ele descreve os padrões de uso WAI-ARIA recomendados e fornece uma introdução aos conceitos por trás deles.
Eles têm guias para construir widgets tipo acordeão, controles deslizantes, tabs e muito mais.
Componentes JavaScript acessíveis
Também existem ótimos recursos com componentes JavaScript acessíveis.
- Exemplos práticos de ARIA.
- Modaal - Modaal é um plugin de janela modal acessível WCAG 2.0 Level AA.
- Frend - Uma coleção de componentes front-end modernos e acessíveis.
- Padrões de projeto A11Y.
Se você conhece recursos adicionais, por favor, compartilhe-os nos comentários.
Recapitulando
Aproveite as vantagens da JavaScript para melhorar a acessibilidade do seu site. Cuide do gerenciamento do foco, informe-se sobre os padrões de uso comuns e considere os usuários de leitores de tela ao manipular o DOM. Acima de tudo, não se esqueça para quem você está fazendo sites e divirta-se fazendo-os.
Indo além
É isso por agora. Espero que essas dicas ajudem você a escrever HTML mais acessível. Um grande obrigado a Heydon Pickering, porque seu livro Inclusive Front-End Design Patterns construiu a base da maioria das coisas que você acabou de ler. Se você quiser aprender mais sobre acessibilidade e design inclusivo, sugiro que você leia o livro dele.
Mais dicas de acessibilidade
Este artigo é o segundo de uma série de quatro. Os próximo está sendo escrito e logo será lançado já foi lançado.
- Escrevendo HTML com acessibilidade em mente
- Escrevendo JavaScript com acessibilidade em mente
- Escrevendo CSS com acessibilidade em mente
- A seguir: Aprenda a projetar e desenvolver com a acessibilidade em mente
Obrigado por ler e por favor não se esqueça de curtir e compartilhar este artigo se você gostou.
Agradecimentos especiais a Adrian Roselli por me ajudar com este artigo e a Eva por revisar minha escrita.
Enquanto trabalho no próximo artigo você pode conferir algumas outras coisas que escrevi:
Uma introdução à acessibilidade da Web. Dicas sobre como melhorar sua marcação e fornecer aos usuários mais e melhores maneiras.
Publicado em medium.com
Uma pequena colecção de técnicas CSS úteis e um lembrete rápido de que as folhas de estilo de impressão ainda são uma coisa.
Publicado em uxdesign.cc
Outras leituras e recursos
Conheça os livros do Maujor®
Ir para a página de entrada nos sites dos livros.