Introdução à ARIA para acessibilidade na Web

Introdução sobre WAI-ARIA, com os principais conceitos de acessibilidade na Web, mostrando ações possíveis de se fazer para sites e apps mais acessíveis.

Ir para o artigo

Acessibilidade Web é um tópico que, apesar de muitíssimo importante, apresenta uma imensa carência de aplicação prática — projetos Web brasileiros não são exceção. E uma das medidas mais importantes para suprir essa lacuna é conhecer mais sobre ARIA.

WAI-ARIA (Accessible Rich Internet Applications ou ARIA) é uma especificação do W3C para aprimorar a acessibilidade (a11y) de maneiras que a HTML puro não consegue.

Quando usado corretamente, ARIA pode:

  • Melhorar a acessibilidade de controles interativos, como menus, sliders, pop-ups etc.;
  • Definir pontos de referência úteis (landmarks) para a estrutura da página;
  • Definir “regiões ativas” (live regions) atualizadas dinamicamente;
  • Melhorar a acessibilidade e interatividade do teclado;
  • E muito mais.

A HTML possui um “vocabulário” (conjunto de tags e atributos) definido, e que evolui com o tempo — por exemplo, foi removido, enquanto foi adicionado.

ARIA fornece novos atributos e valores de código que expandem o vocabulário e a semântica da HTML para facilitar e aprimorar a acessibilidade na Web.

Assim como a HTML, ARIA evolui com o tempo e geralmente é bem suportado em navegadores e leitores de tela modernos — muitas bibliotecas de scripts também oferecem suporte para ARIA.

Componentes ARIA

Os 3 principais Componentes ARIA são roles (funções/papéis), properties (propriedades) e states (estados).

Roles, States e Properties ARIA podem ser definidas na marcação, diretamente, ou podem ser dinamicamente definidas e/ou alteradas usando scripts.

Os Estados e Atributos ARIA sempre começam com “aria-“, por exemplo, aria-required="true".

Roles

As Roles ARIA (Funções/Papéis) definem o que um elemento é ou faz. A maioria dos elementos HTML têm uma função padrão apresentada à tecnologia assistiva — por exemplo, <button> tem uma função padrão de “botão” e <form> tem uma função padrão de “formulário”.

ARIA pode definir roles que não estão disponíveis em HTML e também pode substituir determinadas funções-padrão dos elementos HTML (isso é mais bem explicado na Regra ARIA #2, abaixo).

Um exemplo de role ARIA é <form role="search">. Em HTML, todos os formulários têm a mesma semântica. Mas, com o ARIA, é possível definir a semântica de um formulário específico como sendo um formulário de pesquisa.

Roles padrão de HTML não devem ser duplicadas usando o ARIA, portanto, evite coisas como <button role="button">.

Properties

As Properties ARIA (Propriedades) definem semânticas adicionais não suportadas no HTML padrão.

Um exemplo é <button aria-haspopup="true">. Essa propriedade estende o botão padrão para fazer com que um leitor de tela anuncie que o botão, se ativado, acionará um pop-up.

States

Os States ARIA (Estados) são atributos que definem a condição atual de um elemento.

Eles geralmente mudam com base na interação feita ou em alguma variável dinâmica. Um exemplo é <input aria-invalid="true">. Essa propriedade fará com que um leitor de tela leia essa entrada como inválida no momento (o que significa que precisa ser corrigida), mas esse valor de estado pode ser facilmente alterado para false dinamicamente com base no quê é preenchido.

Landmark Roles

ARIA também pode definir “Pontos de Referência” (Landmark Roles) para áreas ou regiões significativas da página. Eles são identificados por leitores de tela e ajudam na orientação e navegação na página.

As principais landmark roles são:

  • banner. Conteúdo orientado que, normalmente, contém o nome do site, logo, pesquisa e/ou navegação principal (semanticamente, equivalente à <header>);
  • navigation. A área que contém os links de navegação para o documento ou site (semanticamente, equivale à <nav>);
  • main. O conteúdo principal/central do documento (semanticamente, equivalente à <main>);
  • complementary. Conteúdo de apoio/suporte (secundário) para o conteúdo principal (semanticamente, equivalente à <aside>);
  • contentinfo. Conteúdo informativo, como notas de rodapé, direitos autorais, links para declaração de privacidade, links para preferências e assim por diante (semanticamente, equivalente à <footer>);
  • search. Contém a funcionalidade de pesquisa do site (sem elemento HTML correspondente).

Em uma página web típica, o logo e o conteúdo do cabeçalho podem estar dentro de um elemento com a role banner. Os links de navegação na parte superior seriam identificados na navigation (normalmente, contidos dentro de banner).

O formulário de busca, usando <form role="search">; o corpo principal de um artigo seria main; os links relacionados em uma barra lateral, identificados com complementary; o conteúdo do rodapé e os links na parte inferior de uma página teriam uma função de contentinfo.

Regiões genéricas

Todas o pontos de referência ARIA (exceto search) têm regiões HTML equivalentes. Leitores de tela fornecem uma lista de todos os pontos de referência/regiões de uma página e teclas de atalho para navegar entre eles.

Algumas tecnologias assistivas permitem pular para pontos de referência/regiões específicos (por exemplo, pressionando a tecla M para o conteúdo principal).

Se uma área significativa de um site/app não se alinhar com as landmark roles mostradas acima, o atributo role="region" pode ser usado para criar um marco/região genérico. Ele deve ter um nome acessível descritivo definido usando aria-label ou aria-labelledby.

Por exemplo, <div role="region" aria-label="Filtros">.

Regras de como usar ARIA

A especificação ARIA define 5 regras de uso para oferecer suporte à acessibilidade ideal.

Regra ARIA #1: Se puder usar valores semânticos e atributos nativos de HTML, faça isso

HTML é a base da acessibilidade na Web — na verdade, é a base da Web, em si.

ARIA não deve ser usado quando o HTML já fornece semântica suficiente para acessibilidade. Quando usado incorretamente, ARIA pode introduzir barreiras significativas à acessibilidade.

Regra ARIA #2: Não altere a semântica nativa, a menos que você realmente precise

A maioria dos elementos HTML possui semântica e/ou significado próprios, que podem ser transmitidos a usuários de leitores de tela. Quando necessário, ARIA pode substituir e alterar essas semânticas.

Por exemplo, um elemento <ul> define uma lista não ordenada. Quando encontrado por um leitor de tela, ele também é identificado como uma lista não ordenada — leitores de tela também anunciam o número de itens da lista, ativam a navegação dos itens da lista e muito mais.

Se uma função/papel ARIA (role) for adicionada ao <ul> — por exemplo <ul role="navigation"> –, a semântica da lista será substituída e perdida: o elemento, agora, torna-se um ponto de referência de navegação e os benefícios de acessibilidade da lista não ordenada desaparecem.

Em vez disso, a marcação <div role="navigation"><ul>...</ul></div> fornece os benefícios de navegação e os benefícios da lista não ordenada — melhor ainda, <nav><ul>...</ul></nav> é semanticamente equivalente sem depender de ARIA!

Regra ARIA #3: Todos os controles ARIA interativos devem ser utilizáveis com o teclado

Os Padrões de Design ARIA (ARIA Design Patterns) definem interações de teclado padrão para widgets e controles ARIA.

Isso permite que todos usem um widget, por exemplo, através do teclado, e garante que as instruções fornecidas pelos leitores de tela estejam alinhadas com a funcionalidade real de cada página em um site ou app.

Regra ARIA #4: Controles interativos devem ter semântica adequada e não podem ser ocultados

Qualquer elemento que possa receber foco através do teclado (focusable) — principalmente usando a tecla Tab — deve ter semântica adequada para que seja identificado como um link, botão, controle de formulário etc. ou outro elemento com um valor de função apropriado.

Como role="presentation" remove a semântica, esse atributo nunca deve ser aplicado a um elemento focusable.

Da igual maneira, elementos interativos devem estar visíveis; não oculte elementos focados (focused) com CSS ou com aria-hidden="true".

Regra ARIA #5: Todos elemento interativo deve ter um nome acessível

Texto que descreve um controle interativo deve ser apresentado aos usuários do leitor de tela quando o controle for encontrado; um botão deve ter texto descritivo (como “Registrar”) e uma entrada de texto deve ter um rótulo descritivo (como “Nome”).

O conteúdo que os leitores de tela anunciam para identificar um controle é chamado de nome acessível (accessible name). ARIA também pode ser usado para definir esses nomes acessíveis.

ARIA Labels e Descriptions

HTML facilita associações que suportam acessibilidade — <label> para campos de formulário, <caption> para descrições de tabelas de dados, <th> para cabeçalhos de linha e coluna em tabelas de dados etc. Quando o HTML não pode criar as associações necessárias, é aí que ARIA pode ser usado.

Com aria-labelledby, um elemento faz referência ao valor do atributo id (ou, em alguns casos, diversos valores do atributo id) do(s) elemento(s) que contém o texto que atua como seu rótulo descritivo (label).

Por exemplo, esta região será rotulada e identificada pelo texto dentro do <h2>, “Filtros”:

Já com aria-label, é possível atribuir o texto do label diretamente no valor do atributo. No exemplo, mesmo que o conteúdo de <h2> seja “Filtros de Busca”, esta região será rotulada pelo valor aria-label “Filtros”:

A abordagem aria-labelledby é melhor neste caso, já que não duplica o conteúdo e garante que, se o texto do título for alterado, o rótulo da região também será alterado.

Cada elemento interativo também precisa de um texto que descreva sua função, que pode ser atribuído usando aria-describedby. Como aria-labelledby, o valor do atributo id do elemento descritivo é referenciado.

Descrições (Descriptions) normalmente são lidas por leitores de tela após os labels e, às vezes, como a última informação de um elemento. Descrições são mais úteis para campos de formulário.

Observe que o exemplo anterior usa <label> em vez de um label ARIA porque <label> já é o suficiente (consulte a Regra ARIA #1 acima).

“Cálculo”de ARIA Labels e Descriptions

A definição de labels com ARIA vem com algumas restrições e avisos. A maneira como os labels e as descriptions são “calculados” nas páginas é extremamente complexa, mas, a seguir, constam algumas diretrizes gerais.

  • Para ser atribuído a um label ARIA, um elemento deve ser “rotulável” — um link, botão, controle de formulário, ou ter HTML específico ou semântica ARIA. Muitos elementos não são rotuláveis — <p>, <div> e <span>, por exemplo, a menos que seja atribuído um papel ARIA apropriado.
  • Os rótulos ARIA substituem o texto padrão e os nomes acessíveis em elementos HTML. Se uma entrada tiver um <label> e um aria-label ou aria-labelledby, o <label> não será lido — da mesma forma, o texto de um link/botão e os valores do atributo alt de uma imagem serão substituídos pelo texto do label ARIA.
  • Um elemento pode ter apenas um nome acessível, embora seja possível fazer referência a vários ids de elemento com aria-labelledby ou aria-describeby para concatenar vários textos (ex: <table aria-labelledby="tablecaption tabledisclaimer">).
  • WCAG requer que o label de um elemento seja incluído em seu nome acessível (que é lido por um leitor de tela). Ao usar labels ARIA, assegure a consistência entre o que as pessoas sem deficiência veem e o que os usuários de leitores de tela ouvem — importante lembrar que muitos têm alguma visão.
  • Os usuários de leitores de tela podem pausar e explorar o conteúdo de texto da página — até mesmo lendo o conteúdo palavra por palavra ou letra por letra. No entanto, isso não é possível com labels ou descriptions ARIA que, em vez disso, são lidos como um fluxo de texto. Mantenha-os sucintos.
  • Quando o texto associado a aria-labelledby ou aria-describedby é lido, todas as semânticas são removidas. Links, tabelas, listas etc. dentro do elemento referenciado não são identificados quando o label ou texto de descrição é apresentado.
  • A melhor maneira de garantir que labels e descrições ARIA foram implementados corretamente é ouvir em um leitor de tela. Você também pode inspecionar o nome acessível e a descrição de um elemento usando ferramentas de navegador, como as DevTools.

Atualização de conteúdo dinâmico (live regions)

Mudanças dinâmicas de conteúdo podem criar problemas de acessibilidade. O que acontece se um leitor de tela ler um elemento enquanto ele é atualizado?

  • Se o conteúdo atualizado for importante, o usuário deve ser interrompido?
  • O foco deve ser definido imediatamente para o novo conteúdo?
  • O usuário deve simplesmente ser informado sobre a atualização para que possa encontrá-la em outro lugar?
  • Nada deveria acontecer?

ARIA pode sinalizar áreas de página que mudam dinamicamente como regiões ativas (live regions). As regiões ativas tornam as atualizações de conteúdo compatíveis com leitores de tela, informando sobre as atualizações, fornecendo controles para a região ativa, determinando a quantidade de novo conteúdo que é lido e muito mais.

Para criar uma live region, é preciso usar a propriedade aria-live no elemento que será atualizado. Este atributo deve ser definido quando a página é carregada pela primeira vez; injetar mais tarde não funciona de maneira confiável.

O atributo aria-live assume os valores off, polite ou assertive, que especifica o que um leitor de tela deve fazer quando o elemento é atualizado.

Um valor off (aria-live="off") informa ao leitor de tela para não anunciar a atualização. Se o usuário do leitor de tela posteriormente encontrar o conteúdo atualizado, ele será lido nesse momento.

Isso seria usado para atualizações de conteúdo irrelevantes ou menos importantes — é útil principalmente para live regions que mudam dinamicamente de polite ou assertive para off usando script.

O valor polite fará com que o conteúdo atualizado seja lido pelo leitor de tela na próxima pausa lógica. Este valor é mais comum para notificação de status, atualizações de widgets (clima, cotação etc.), mensagens de bate-papo e coisas assim.

O valor assertive anunciará a mudança de conteúdo imediatamente — possivelmente, quando o usuário do leitor de tela estiver ouvindo outro conteúdo da página — assertive é recomendado para atualizações críticas, como mensagens de erro.

É necessário cuidado com todas as live regions para garantir que os usuários do leitores de tela não sejam desnecessariamente interrompidos ou sobrecarregados com notificações, especialmente se houver várias regiões ativas em uma página — testar a página em um leitor de tela revelará rapidamente se esse é o caso.

Acessibilidade de teclado de widgets ARIA

Exemplos de widgets incluem sliders, dropdowns, controles de arrastar e soltar (drag-and-drop), caixas de texto de preenchimento automático, janelas de diálogo e tooltips, só para citar alguns. Eles são elementos interativos criados e controlados por meio de scripts. Widgets (geralmente) não são nativos na HTML ou são controles HTML bastante aprimorados por meio de scripts.

Os widgets não são nativamente acessíveis e o HTML tem marcação muito limitada para definir widgets complexos. No entanto, ao estabelecer um conjunto-padrão de funções, propriedades e estados, ARIA ajuda a implementar a acessibilidade com relativa facilidade.

Homem com braço quebrado mexendo no computador. ARIA com certeza pode ajudar neste tipo de situação.

ARIA Design Patterns and Widgets fornece requisitos específicos para a criação de uma ampla variedade de widgets. É vital que esta orientação seja seguida! Abaixo, algumas considerações de alto nível.

Em HTML, apenas links e controles de formulário podem receber o foco do teclado. Conforme a pessoa pressiona Tab para navegar por uma página, o navegador para ou define o foco apenas nesses tipos de elementos, permitindo que eles sejam ativados e manipulados.

Com scripts e CSS, outros elementos de página (como <p> ou <span>) podem aparecer e se comportar como controles interativos para usuários de mouse com visão. Sem esforço adicional, entretanto, eles não seriam acessíveis pelo teclado nem identificados como controles interativos para um usuário de leitor de tela.

Para evitar essa perda de funcionalidade, use a marcação HTML sempre que possível (por exemplo, <button> para elementos que funcionam como botões, <a> para links, <select> para menus selecionados etc.). De qualquer maneira, quando widgets personalizados são necessários, ARIA pode ajudar a preencher essa lacuna.

Os controles-padrão HTML normalmente devem ser usados para fornecer interatividade com o teclado. Como alternativa, um elemento que não pode receber foco nativamente (como um <div>) pode ser focalizado usando o atributo tabindex:

  • tabindex="0" torna qualquer elemento focalizável usando o teclado ou script, como se fosse um link ou botão.
  • tabindex="-1" torna qualquer elemento focalizável com script, mas não com o teclado.
  • Valores positivos (tabindex="1" ou superior) devem sempre ser evitados. Eles forçam uma ordem de navegação artificial na página que destrói a ordem natural.

Ao aplicar tabindex="0", o navegador irá definir o foco para o elemento na ordem de navegação normal quando for pressionada a tecla Tab. Isso permite que um elemento seja interativo, como a funcionalidade de acionamento quando o elemento recebe o foco do teclado ou quando se pressiona uma tecla enquanto o elemento está em foco.

Isso às vezes é necessário com certos widgets ARIA, como navegação por abas, menus e controles de árvore (tree controls). A funcionalidade do teclado deve estar alinhada com os requisitos do ARIA Design Pattern para garantir que o widget forneça padrões de interação de teclado.

tabindex="-1" permite que um elemento receba o foco programaticamente — quando se segue um link para o elemento (âncoras HTML) ou quando o foco é definido com script (por exemplo, document.getElementById('errormessage').focus()). Isso é especialmente útil para mensagens de erro, caixas de diálogo etc. que não são controles HTML focalizáveis nativamente, mas que você deseja ter como foco para acessibilidade ideal.

Uma vez que um widget pode ser focalizado pelo teclado, ele deve ter um nome descritivo acessível usando valores HTML (como texto de botão), associações (como <label>) ou, se não for possível usando HTML, usando aria-labelledby ou aria-label.

Além disso, o elemento deve ter um valor de ARIA role apropriado. Isso garante que o usuário do leitor de tela seja informado sobre o que é o widget e o que ele faz. Isso também pode fazer com que o leitor de tela anuncie instruções específicas do widget sobre como interagir com ele.

Certos widgets também requerem estados e propriedades ARIA para informar o leitor de tela e oferecer suporte à acessibilidade do teclado.

Expandindo os recursos de foco no navegador para elementos que de outra forma não poderiam receber foco e fornecendo nomes acessíveis adequados e marcação ARIA, é possível atingir grande flexibilidade e poder para construir widgets e interfaces complexos, que são altamente acessíveis.

Exemplos de uso ARIA

Depois de explicados os conceitos básicos sobre ARIA, convém mostrar alguns exemplos para constatar que, além de altamente benéfico para projetos Web e aprimorador de acessibilidade, é relativamente simples de ser construído.

Formulários

ARIA consegue melhorar a acessibilidade de formulários de uma maneira que não é possível com o padrão de HTML.

  • aria-labelledby e aria-label permitem associações complexas de texto para inputs (de maneiras que <label> não consegue);
  • aria-describeby associa descrições secundárias a inputs, como requisitos de campo ou mensagens de erro;
  • aria-required="true" identifica inputs que requerem entrada de dados da pessoa;
  • aria-invalid="true" identifica inputs que estão em estado de erro;
  • role=”radiogroup”, quando dado um ARIA label, fornece a mesma funcionalidade que <fieldset>/<legend> para grupos de entradas, mas com mais flexibilidade.

Botões

A semântica de botões pode ser aprimorada em botões com funções especializadas.

  • <button aria-haspopup="dialog"> faz com que os leitores de tela anunciem que o botão aciona uma janela de diálogo — valores adicionais de aria-haspopup de menu, listbox, tree, grid e true também estão disponíveis;
  • <button aria-expanded="true | false"> pode ser usado em botões que expandem ou reduzem o conteúdo (accordions); a definição dos valores apropriados informa aos leitores de tela o estado do botão e se o conteúdo a seguir está disponível ou não;
  • <button aria-pressure = "true | false"> indica se um botão de alternância (toggle) está pressionado/ativo ou não.

Elementos decorativos/ornamentais

O atributo role="presentation" remove a semântica nativa de um elemento HTML, tornando-o semelhante a um ou .

Isso pode ser útil se um elemento HTML for usado para controlar a apresentação/layout ou se a semântica nativa do elemento não for apropriada.

Exemplos comuns incluem tabelas de layout, listas usadas para estrutura de apresentação e elementos <svg> que não precisam de texto alternativo.

Scalable Vector Graphics (SVG)

A acessibilidade para elementos <svg> ainda não é robusta. Felizmente, ARIA pode ser usado para garantir que o conteúdo dos elementos SVG seja mais acessível.

No exemplo a seguir, o atributo role="img" define o elemento como sendo uma imagem. O nome acessível (texto alternativo) é definido usando aria-labelledby, que faz referência ao elemento <title> dentro do SVG:

O próximo exemplo também tem role="img", mas usa aria-label para definir o texto alternativo:

Para SVGs puramente decorativos (ou de texto acessível adjacente à imagem), então <svg role="presentation"> ocultaria efetivamente o elemento — semelhante a <img alt="">.

Conclusão

Nesta introdução à ARIA para acessibilidade na Web, foram explicados os conceitos e marcações básicas rumo a conseguir sites e apps mais acessíveis.

Como é de notar, são pequenas medidas e acréscimos ao código que já podem fazer uma grande diferença na experiência de uso de muitas pessoas.

O quanto sua equipe e/ou empresa em que você trabalha estão preocupados e investindo em WAI-ARIA para garantir maior abrangência de acessibilidade na Web?