A Rede Mundial está mudando. Estatísticamente, os sítios baseados em páginas estão, cada vez mais, sendo repostos por aplicações dinâmicas, em estilo Ambiente, que fazem uso intenso de JavaScript e AJAX. Estilistas estão criando novos widgets e controles inteiramente com a combinação de JavaScript, HTML e CSS. Este salto tem o potencial de aperfeiçoar, dramaticamente, a capacidade de resposta e a usabilidade da Rede, mas milhares de utilizadores estão sob o risco de exclusão, devido a algumas lacunas na acessibilidade. A JavaScript tem, tradicionalmente, tido a reputação de ser inviável para quem usa tecnologias assistivas, como leitores de tela mas, agora, existem maneiras de criar interfaces de utilização dinâmicas acessíveis a uma ampla variedade de pessoas.
O problema
A maior parte do conjunto de ferramentas JavaScript oferece uma biblioteca de utilização de widgets que imita o comportamento de interfaces de Ambiente familiares. Deslizantes, barras de menus, visão de arquivos em lista e muito mais pode ser construído com uma combinação de JavaScript, CSS e HTML. Uma vez que a especificação da HTML 4 não fornece etiquetas integradas (built-in tags) que descrevam estes tipos de widgets semanticamente, os desenvolvedores recorrem ao uso de elementos genéricos, tais como <div> e <span>. Embora isto resulte em um widget que se pareça com seu duplo de ambiente, geralmente não existe informação semântica suficiente, na marcação, para torná-lo utilizável por uma tecnologia assistiva. Teor dinâmico em uma página da Rede Mundial pode ser particularmente problemático para quem, por alguma razão, não pode ver a tela. Cotações de ações, alimentação instantânea de atualizações do twitter, indicadores de progresso e conteúdos similares alteram o DOM, enquanto uma tecnologia assistiva (TA/AT) pode não ser alertada disso. Aqui é onde o conjunto ARIA entra.
Exemplo 1: Marcação para um widget de abas construído sem as indicações ARIA. Não existem informações semânticas, na marcação, que descrevam a sua forma, nem a sua função.
<!-- This is a tabs widget. How would you know, looking only at the markup? -->
<ol>
<li id="ch1Tab">
<a href="#ch1Panel">Chapter 1</a>
</li>
<li id="ch2Tab">
<a href="#ch2Panel">Chapter 2</a>
</li>
<li id="quizTab">
<a href="#quizPanel">Quiz</a>
</li>
</ol>
<div>
<div id="ch1Panel">Chapter 1 content goes here</div>
<div id="ch2Panel">Chapter 2 content goes here</div>
<div id="quizPanel">Quiz content goes here</div>
</div>
Exemplo 2: Como o widget de abas pode ser visto. Seus utilizadores podem reconhecer sua aparência, mas não há semântica legível por mecanismos de tecnologias assistivas.
ARIA
As definições para WAI-ARIA Accessible Rich Internet Applications (Aplicações Ricas para uma Internete Acessível), da W3C - Web Accessibility Initiative (Iniciativa pela Acessibilidade na Rede Mundial/World Wide Web Consortium-W3C) - oferecem uma via para a adição das necessidades semânticas perdidas pelas tecnologias assistivas, como os leitores de tela. O conjunto ARIA possibilita que desenvolvedores possam descrever seus widgets de forma mais detalhada com a inclusão de atributos especiais à marcação. Projetado para preencher a lacuna entre o padrão de rotulagem HTML e os controles com estilo ambiente encontrados em aplicações dinâmicas pela web, o conjunto ARIA fornece funções (roles) e estados (states) que descrevem o comportamento da maioria das interfaces de utilização dos widgets conhecidas.
A especificação ARIA está dividida em três tipos diferentes de atributos: funções (roles), estados (states) e propriedades (properties). As funções (roles) descrevem os widgets que não estão disponíveis de outra forma em HTML 4, como deslizantes, barras de menu, abas e diálogos. As propriedades (properties) descrevem as características desses widgets - se podem ser arrastados (draggable), se existe algum elemento obrigatório, ou se trazem uma janela de explosão (popup) associada. Os estados (states) descrevem a interação atual de um elemento, informando à tecnlogia assistiva se este se encontra ativo, desativado, selecionado, ou oculto.
Os atributos ARIA são projetados para serem interpretados automaticamente pelo navegador e traduzidos para as APIs (Application Programming Interface/Interface de Programação de Aplicativo) de acessibilidade nativas do sistema operacional. Quando o conjunto ARIA está presente as tecnologias assistivas são capazes de reconhecer e interagir com os controles personalizados pela JavaScript da mesma forma que fazem com os seus equivalentes de ambiente. Isto tem o potencial de oferecer uma experiência de utilização muito mais consistente do que aquela que foi possível nas gerações anteriores das aplicações da Rede, uma vez que os utilizadores de tecnologias assistivas podem empregar todo o seu conhecimento sobre o funcionamento das aplicações de ambiente, ao usar aquelas que são baseadas na web.
Exemplo 3: Marcação para um widget de abas com os atributos ARIA adicionados:
<!-- Now *these* are Tabs! -->
<!-- We've added role attributes to describe the tab list and each tab. -->
<ol role="tablist">
<li id="ch1Tab" role="tab">
<a href="#ch1Panel">Chapter 1</a>
</li>
<li id="ch2Tab" role="tab">
<a href="#ch2Panel">Chapter 2</a>
</li>
<li id="quizTab" role="tab">
<a href="#quizPanel">Quiz</a>
</li>
</ol>
<div>
<!-- Notice the role and aria-labelledby attributes we've added to describe these panels. -->
<div id="ch1Panel" role="tabpanel" aria-labelledby="ch1Tab">Chapter 1 content goes here</div>
<div id="ch2Panel" role="tabpanel" aria-labelledby="ch2Tab">Chapter 2 content goes here</div>
<div id="quizPanel" role="tabpanel" aria-labelledby="quizTab">Quiz content goes here</div>
</div>
O conjunto ARIA tem suporte nas últimas versões de todos os maiores navegadores, incluindo Firefox, Safari, Opera, Chrome e Internet Explorer. Muitas das tecnologias assistivas, como as de código aberto NVDA e os leitores de tela Orca, da mesma foma, trazem suporte ao ARIA. Progressivamente, as bibliotecas JavaScript para widget, tais como jQuery UI, YUI, Google Closure e Dojo Dijit também incluem as marcações ARIA.
Mudanças na apresentação
Mudanças de apresentação dinâmicas agregam o uso de CSS para alterar a aparência do conteúdo (uma borda vermelha em volta de algum dado inválido, ou a troca da cor de fundo de uma caixa de seleção já marcada), bem como quando um item é exibido, ou escondido.
Mudanças de estado
O conjunto ARIA provê atributos para declarar o estado atual da interface de utilização de um widget. Os exemplos abrangem (mas não são apenas estes, com certeza( :
aria-checked
(marcada)
: indica o estado de uma caixa de seleção, ou de um botão de alternativa (radio
)aria-disabled
(desativado)
: indica que um elemento está visível, mas não pode ser editado, tampouco é executável.aria-grabbed
(arrastado)
: indica o estado "arrastado" para um objeto, em uma operação de "arrastar e soltar".
(Para uma lista completa de estados ARIA, consulte a ARIA list of states and properties (lista de estados e propriedades ARIA).
Os desenvolvedores devem dar preferência ao uso dos estados ARIA para indicar a situação atual dos elementos widgets na interface de utilização (UI) e os seletores de atributos CSS para alterar a sua aparência, com base nas mudanças desses estados (em vez de usar um roteiro (script) para mudar um nome de classe de um elemento).
A Open Ajax Alliance (OAA - Aliança OpenAJAX ) disponibiliza um exemplo de um seletor de atributos CSS baseado nos estados ARIA (em inglês) - an example of CSS attribute selectors based on ARIA states. O exemplo mostra a interface de um editor WYS/WYG com um sistema de menu dinâmico. Os itens selecionados no menu, como o tipo de fonte estão, visualmente, distintos dos outros. As partes importantes do exemplo são explicadas a seguir.
Neste exemplo, a HTML para um menu tem a forma exibida abaixo. Note como, nas linhas 7 e 13, a propriedade (property) aria-checked
é usada para declarar o estado da seleção dos itens do menu.
Exemplo 1a: HTML para um menu selecionável (adaptado da https://www.oaa-accessibility.org/example/25/).
<ul id="fontMenu" class="menu" role="menu" aria-hidden="true"> <li id="sans-serif" class="menu-item" role="menuitemradio" tabindex="-1" aria-controls="st1" aria-checked="true">Sans-serif</li> <li id="serif" class="menu-item" role="menuitemradio" tabindex="-1" aria-controls="st1" aria-checked="false">Serif</li> ...
A CSS usada para alterar a aparência do item selecionado é mostrada no Exemplo 1b. Perceba que não existe um nome de classe (classname) de personalização, apenas o estado do atributo aria-checked
, na linha 1.
Exemplo 1b: Seletor baseado em atributo para indicar um estado (da https://www.oaa-accessibility.org/example/25/).
li[aria-checked="true"] { font-weight: bold; background-image: url('/images/dot.png'); background-repeat: no-repeat; background-position: 5px 10px; }
O JavaScript para atualizar a propriedade aria-checked
tem a forma exibida no Exemplo 1c. Repare que o roteiro (script) apenas atualiza o atributo aria-checked
(linhas 3 e 8); também não é necessário adicionar, ou remover, um nome de classe personalizada.
Exemplo 1c: A JavaScript atualiza o atributo aria-checked (baseado em https://www.oaa-accessibility.org/example/25/).
var processMenuChoice = function(item) { // 'check' the selected item item.setAttribute('aria-checked', 'true'); // 'un-check' the other menu items var sib = item.parentNode.firstChild; for (; sib; sib = sib.nextSibling ) { if ( sib.nodeType === 1 && sib !== item ) { sib.setAttribute('aria-checked', 'false'); } } };
Alterações visuais
Quando o conteúdo visual é alterado (isto é, um elemento é escondido, ou mostrado), os desenvolvedores devem mudar o valor da propriedade aria-hidden
. As técnicas descritas acima devem ser usadas, a fim de declarar a CSS para ocultar um elemento utilizando
display:none
(exibir:nenhum).
O sítio da Open Ajax Alliance fornece um exemplo de uma dica de tela (tooltip) que utiliza o estado aria-hidden para controlar a sua visibilidade (em inglês) an example of a tooltip that uses aria-hidden
to control the visibility of the tooltip. O exemplo mostra um formulário web simples, com caixas de dicas de tela contendo instruções associadas aos campos de entrada. As partes relevantes deste exemplo estão explicadas abaixo.
Aqui, a HTML para a dica de tela tem a forma exibida no Exemplo 2a. A linha 9 configura o estado da aria-hidden
para true
.
Exemplo 2a: HTML para dicas de tela (adaptado de https://www.oaa-accessibility.org/example/39/).
<div class="text"> <label id="tp1-label" for="first">First Name:</label> <input type="text" id="first" name="first" size="20" aria-labelledby="tp1-label" aria-describedby="tp1" aria-required="false" /> <div id="tp1" class="tooltip" role="tooltip" aria-hidden="true">Your first name is optional</div> </div>
A CSS para esta marcação está explicada no Exemplo 2b. Veja que não há uso de classname personalizada, apenas o estado do atributo aria-hidden
, na linha 1.
Exemplo 2b: Seletor basedo em atributo para indicar um estado (de https://www.oaa-accessibility.org/example/39/).
div.tooltip[aria-hidden="true"] { display: none; }
O JavaScript que atualiza a propriedade aria-hidden
tem a forma exposta no Exemplo 2c. Observe que o roteiro apenas atualiza o atributo aria-hidden
(linha 2); não é necessário adicionar, nem remover, uma classname customizada.
Exemplo 2c: JavaScript para atualização do atributo aria-checked (com base em https://www.oaa-accessibility.org/example/39/).
var showTip = function(el) { el.setAttribute('aria-hidden', 'false'); }
Mudança de Atributo (Role)
O conjunto ARIA possibilita que os desenvolvedores possam declarar uma função semântica para um elemento que, de outro modo, não a apresentaria, ou a ofereceria de forma incorreta. Por exemplo, quando alguma lista desordenada é utilizada para criar um menu, à
<ul>
deve ser dada uma
role
de menubar
e cada
<li>
deve ter uma role
de menuitem
.
O papel (role
) de um elemento não deve mudar. Em vez disso, remova o elemento original e ocupe seu lugar com um elemento que tenha a função (role
) nova.
Por exemplo, considere um widget de edição "inline": um componente que possibilita que seus utilizadores sejam capazes de editar uma parte de um texto, sem mudar toda a composição. Este componente carrega o modo "visualizar", no qual o texto não pode ser modificado, mas pode ser ativado e um modo "editar", no qual o texto pode ser alterado. Se você o desenvolve, pode ter a tentação de implementar o modo "visualizar" com o uso do elemento texto "somente leitura" <input>
, definindo a sua ARIA
role
para button
e, em seguida, alternando para o modo "editar", para tornar o elemento apto à gravação e removendo o atributo role
no modo "editar" (desde que os elementos <input>
tenham as suas próprias funções semânticas).
Não faça isso. Em substituição, implemente o modo "visualizar" usando um elemento completamente diferente, tal como uma <div>
, ou <span>
com uma role
de button
e o modo « edit » utilizando um elemento texto <input>
.
Mudanças assíncronas de conteúdo
Navegação pelo Teclado
Muitas vezes, os desenvolvedores negligenciam o suporte ao teclado quando criam widgets personalizados. Para ser acessível a uma gama maior de pessoas, todas as configurações de uma aplicação web, ou de um widget, devem oferecer controles pelo teclado, sem a necessidade de um rato. Na prática isto, frequentemente, envolve as convenções suportadas por widgets similares, de ambiente, tirando plena vantagem das teclas Tab, Entra, Barra de Espaço e Setas.
Tradicionalmente, a navegação pelo teclado na web tem sido limitada à tecla Tab, que é pressionada para dar foco a cada botão, vínculo, ou formulário na página, em uma ordenação linear e Shift-Tab para navegar em sentido contrário (navegação regresssiva). É uma forma unidimensional de navegação - para frente e para trás, um elemento por vez. Em páginas mais pesadas, alguém que navegue apenas pelo teclado deve pressioná-lo dezenas de vezes antes de alcançar a seção desejada. Implementar as convenções para teclado no modelo ambiente, para a web, tem o potencial de tornar a navegação significativamente mais rápida para essas pessoas.
Aqui está um resumo sobre como a navegação pelo teclado deve funcionar, com a habilitação do conjunto ARIA, na aplicação web:
- A tecla TAB deve fornecer o foco para o widget, como um todo. Por exemplo, a tabulação em uma barra de menu deve ter seu foco em seu primeiro elemento.
- As teclas de setas devem permitir uma seleção, ou a navegação dentro do widget. Por exemplo, as setas "esquerda" e "direita" devem levar o foco para o item anterior, ou próximo, do menu.
- Quando o widget não estiver dentro de um formulário, as teclas "Entra" e "barra de espaço" devem selecionar, ou ativar o controle.
- Dentro de um formulário, a tecla "barra de spaço" deve selecionar, ou ativar um controle, enquanto a tecla "Entra" deve submeter sua ação padrão.
- Se houver dúvidas, copie o comportamento das ações padronizadas para ambiente nos controles que você estiver criando.
Assim, para o exemplo de widget de abas acima, a pessoa que estiver navegando deve ser capaz de entrar e sair da caixa que o contém usando as teclas "Tab" e "Shift+Tab" ( a <ol> na nossa marcação). Uma vez que o foco, pelo teclado, estiver dentro do contêiner, as teclas de setas devem permitir a navegação entre as suas diferentes guias (os elementos <li> ). A partir daqui as convenções variam de plataforma para plataforma. No Windows, a próxima aba deve ser ativada, automaticamente, quando as teclas de setas forem pressionadas. Em Mac OS X, seus utilizadores ativam a próxima aba pressionando a tecla "Entra", ou a "barra de espaço". Um tutorial abrangente, para a criação de widgets, com navegação pelo teclado, descreve como implementar esse comportamento utilizando JavaScript Keyboard-navigable JavaScript widgets (JavaScript para widgets navegáveis pelo teclado).
Para mais detalhes sobre as convenções da navegação pelo teclado em modelo ambiente, um guia completo (em inglês) DHTML style guide (guia de estilos da HTML Dinâmica) está disponível. Este guia oferece uma visão global de como a navegação pelo teclado deve funcionar em cada tipo de widget suportado pelo conjunto ARIA. A W3C também oferece um documento que ajuda muito, ARIA Best Practices, incluindo a navegação pelo teclado e as convenções de atalhos para uma variedade de widgets.