O Chrome DevTools está lançando uma árvore de acessibilidade completa para que os desenvolvedores tenham uma visão geral de toda a árvore. Nesta postagem, descubra como essa árvore é criada e como usá-la no seu trabalho.
O que é a árvore de acessibilidade?
Tecnologias adaptativas, como leitores de tela, usam a API de acessibilidade do Chromium para interagir com conteúdo da Web. O modelo dessa API é a árvore de acessibilidade: uma árvore de objetos usados pela tecnologia adaptativa para consultar atributos e propriedades e realizar ações. Os desenvolvedores Web moldam e manipulam a árvore de acessibilidade principalmente por meio de propriedades DOM, como atributos ARIA para HTML.
No Chrome DevTools, disponibilizamos o painel de acessibilidade para ajudar os desenvolvedores a entender como o conteúdo deles é exposto à tecnologia adaptativa. De modo concreto, quando um nó é selecionado no visualizador de árvore do DOM, as propriedades do nó de acessibilidade correspondente são exibidas no painel com uma visualização dos ancestrais do nó e dos filhos imediatos dele.
Como a árvore é criada?
Antes de vermos como é essa nova visualização em árvore completa no DevTools, vamos abordar brevemente o que é a árvore de acessibilidade em termos mais tangíveis. A árvore de acessibilidade é um derivado da árvore do DOM. A estrutura dela é praticamente a mesma, mas simplificada para remover nós sem conteúdo semântico, como um elemento <div>
usado puramente para fins de estilo. Cada nó na árvore tem um papel, como Button
ou Heading
, e geralmente um nome que pode ser de atributos ARIA ou derivado do conteúdo do nó. Se olharmos para um documento HTML:
<html>
<head>
<title>How old are you?</title>
</head>
<body>
<label for="age">Age</label>
<input id="age" type="number" name="age" value="42">
<div>
<button>Back</button>
<button>Next</button>
</div>
</body>
</html>
O renderizador no Chromium, chamado Blink, deriva uma árvore de acessibilidade interna mais ou menos da seguinte maneira.
role='rootWebArea' focusable name='How old are you?'
role='genericContainer' ignored
role='genericContainer' ignored
role='labelText'
role='staticText' name='Age'
role='spinButton' editable focusable name='Age' value='42'
role='genericContainer' editable
role='staticText' editable name='42'
role='genericContainer'
role='button' focusable name='Back'
role='staticText' name='Back'
role='button' focusable name='Next'
role='staticText' name='Next'
Essa representação contém vários nós supérfluos com o papel genericContainer
, que aparentemente contradiz a declaração acima de que a árvore de acessibilidade é uma derivada simplificada da árvore do DOM. Ainda assim, a maioria desses nós só ocorre na árvore interna e não seriam expostos à tecnologia assistiva. Como o DevTools coleta as informações de acessibilidade diretamente do processo do renderizador, essa é a representação de árvore que o DevTools processa.
Árvore de acessibilidade completa no DevTools
A nova árvore de acessibilidade completa é sincronizada com a árvore do DOM para que os desenvolvedores possam alternar entre as duas árvores. Esperamos que a nova árvore se torne mais explorável, útil e fácil de usar.
Agora que você sabe como a árvore de acessibilidade funciona, você pode usar o DevTools para ver a aparência da nova visualização em árvore. O seguinte documento HTML com um título, cabeçalho e dois botões é usado para mostrar a árvore.
<!DOCTYPE html>
<title>Test</title>
<h1>Heading for example page</h1>
<div>
<button>Back</button>
<button>Next</button>
</div>
A visualização em árvore anterior só permitiria explorar um único nó e os ancestrais dele.
Agora, quando você ativa ou desativa a nova árvore, ela substitui a visualização em árvore do DOM e permite que você veja a árvore de acessibilidade completa da página:
Construção lenta de árvores
Para que a árvore tenha um bom desempenho mesmo em sites maiores, a árvore é construída lentamente no front-end à medida que é explorada. Quando um nó é expandido na árvore, os filhos dos nós são buscados pelo protocolo do Chrome DevTools (CDP), e a árvore é reconstruída.
Ao vivo
A nova visualização em árvore é ativada e atualizada dinamicamente se a árvore de acessibilidade mudar no renderizador. Ele se conecta à mesma mecânica que notificaria a tecnologia assistiva sobre mudanças na árvore e a usa para emitir eventos para o front-end do DevTools com nós atualizados. Na prática, o back-end do CDP detecta atualizações da árvore, rastreia quais nós foram solicitados antes e envia eventos para o front-end do DevTools se algum desses nós mudar.
A história das muitas árvores
Na descrição do que é a árvore de acessibilidade, você aprendeu como o Blink constrói uma árvore de acessibilidade para o DOM que está renderizando, e o DevTools busca essa árvore pelo CDP. Embora isso seja verdade, deixamos algumas complicações nessa descrição. Na realidade, há muitas maneiras diferentes de usar a árvore de acessibilidade no Chromium. Ao projetar a nova visualização em árvore para DevTools, fizemos algumas escolhas ao longo do caminho sobre qual parte dos componentes internos de acessibilidade do Chromium queríamos exibir.
Plataformas
Cada plataforma tem uma API de acessibilidade diferente e, embora a forma da árvore seja a mesma em todas as plataformas, a API para interagir com a árvore é diferente, e os nomes dos atributos podem ser diferentes. O DevTools mostra a árvore interna do Chromium, em que as funções e os atributos tendem a corresponder aos definidos na especificação ARIA (link em inglês).
Isolamento de sites e vários frames
Como o Chromium não apenas coloca o conteúdo de cada guia em diferentes processos de renderizador, mas também isola documentos entre sites em diferentes processos de renderizador, temos que conectar cada documento filho fora do processo separadamente pelo CDP e buscar a árvore de acessibilidade. Em seguida, juntamos essas subárvores no front-end para criar a ilusão de uma árvore coerente, embora elas estejam em diferentes processos de renderizador no Chromium.
Nós ignorados e desinteressantes
Ocultamos alguns nós por padrão: nós ignorados e nós com papel "genérico" sem nome. Esses nós não têm significado semântico e, no caso de nós ignorados, não são expostos à tecnologia adaptativa. Ocultamos esses nós para evitar sobrecarregar a visualização em árvore. Se não fizéssemos isso, a árvore de acessibilidade da maioria das páginas da Web ficaria assim:
A ressalva aqui é que isso significa basicamente que precisamos construir outra árvore que não está disponível no back-end. Digamos, por exemplo, que temos nós A, B, C e X, em que A tem o filho X e B e X tem o filho C. Se X for um nó ignorado, podemos remover X da árvore e criar uma árvore em que C é filho de A.
No front-end, construímos a árvore completa, incluindo nós ignorados, e somente os podamos antes de renderizar os nós. Fazemos isso por dois motivos:
- Ele simplifica muito o gerenciamento das atualizações de nós no back-end, já que temos a mesma estrutura de árvore nos dois endpoints. Por exemplo, se o nó B fosse removido no exemplo, receberíamos uma atualização para o nó X (já que seus filhos mudaram), mas se tivéssemos removido esse nó, teríamos dificuldade para descobrir o que atualizar.
- Ela garante que todos os nós do DOM tenham um nó de acessibilidade correspondente. Quando a árvore é alternada, selecionamos o nó correspondente ao que está atualmente selecionado na árvore DOM. Portanto, no exemplo anterior, se o usuário alternar a árvore enquanto o nó DOM correspondente a X estiver selecionado, injetaremos X entre os nós A e B e selecionaremos X na árvore. Isso permite que o usuário inspecione o nó de acessibilidade para todos os nós DOM e ajuda a determinar por que o nó foi ignorado.
Ideias futuras
O lançamento da nova árvore de acessibilidade é apenas o começo. Temos algumas ideias para projetos futuros que poderíamos desenvolver com base na nova visualização, mas também queremos ouvir seu feedback.
Filtros alternativos
Conforme explicado acima, no momento filtramos os nós que não são considerados interessantes. É possível desativar esse comportamento e mostrar todos os nós, ou ainda oferecer filtros alternativos, como Mostrar nós de pontos de referência ou Mostrar títulos.
Destacar problemas de acessibilidade
Podemos incorporar uma análise de “práticas recomendadas de acessibilidade” com a árvore e destacar os problemas de acessibilidade diretamente nos nós problemáticos.
Mostrar ações de acessibilidade no DevTools
A árvore que mostramos atualmente é puramente unidirecional: ela nos permite ter uma ideia de quais informações seriam alimentadas para a tecnologia assistiva ao navegar em uma página da Web específica. As ações de acessibilidade representam a comunicação na outra direção: elas permitem que a tecnologia adaptativa atue sobre a interface apresentada. Podemos mostrar essas ações no DevTools para permitir ações como “clicar”, rolar ou mudar valores na página usando a API disponível para tecnologia adaptativa.