Complementando elementos textuais para leitores de tela
Ao digitar o conteúdo de nossas páginas web, muitas vezes utilizamos siglas, abreviações e outros elementos visuais que são triviais para usuários videntes, mas que não conseguem ser interpretadas corretamente por leitores de tela (screen readers). Assim, a acessibildade do site fica prejudicada.
Recentemente, aqui no Elo7, enfrentamos o seguinte problema: como fazer com que nossos cards de produtos sejam lidos da forma esperada por leitores de tela? Por exemplo, tendo um preço com fonte menor e tachada, e outro com fonte maior, é possível entender que o primeiro é o preço original, enquanto o segundo é o promocional. No entanto, um leitor de tela lê os dois preços da mesma forma, sem distinção. No caso de parcelamento, interpretamos o texto "12x sem juros"
como "doze vezes sem juros"
, enquanto um leitor de tela lê "12 xis sem juros"
.
Neste post, veremos exemplos (visuais e com áudios de leituras de tela) dos problemas citados e como resolvê-los usando apenas atributos ARIA (link externo) do HTML e um pouquinho de CSS!
Entendendo melhor o problema
Vale notar que este problema ocorre pelo fato de usarmos elementos puramente textuais. No caso de elementos não-textuais, como imagens e ícones, conseguimos usar atributos HTML como alt
e aria-label
para descrever seus conteúdos. Para tags textuais como <p>
e <h1>
, o leitor de telas dá preferência para o texto visível. Logo, caso uma tag textual possua aria-label
, o leitor ignora e lê apenas o conteúdo da tag.
Também é importante saber que não há um padrão de implementação dos screen readers. Nos exemplos a seguir, usamos o NVDA (link externo, em inglês) versão 2020.3 no Windows 10. Assim, caso você use outro leitor ou sistema operacional, há possibilidade de se obter outros resultados.
Exemplificando
No CodePen a seguir, está um exemplo de card de produto - parecido com o de nosso site, com algumas adaptações - que contém os problemas descritos na introdução deste artigo:
O exemplo acima é fictício, então não se assuste com o preço! Preste atenção no HTML. Note que temos aria-labels
mais descritivos nos elementos do card.
Agora, no áudio a seguir temos a leitura deste componente feita via NVDA:
Transcrição do áudio: “Frame. Figura. Origami Tsuru Colorido (Um unid). Sessenta reais, quarenta e oito reais, doze xis sem juros de quatro reais, quê tê dê min dez, frete grátis, legenda.”
Confuso, não? Como foi dito anteriormente, o preço original e o promocional são lidos sequencialmente, sem diferenciação. Além disso, tanto a leitura do parcelamento quanto da quantidade mínima não ficaram claras. Isso se agrava se levarmos em conta que aqueles que utilizam screen readers configuram a leitura para algo muito mais rápido do que o exemplo acima.
E agora, o que fazer?
Resolvendo o problema
O Wordpress criou uma solução para este problema usando CSS (link externo, em inglês) - e não se preocupe pois ela não funciona exclusivamente com Wordpress!
Basta usarmos esta classe:
.screen-reader-text {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
word-wrap: normal !important;
}
Vamos adaptar o conteúdo do primeiro CodePen e adicionar esta classe para nos ajudar com a leitura de nosso card:
Podemos ver que visualmente o card continua o mesmo, mas notamos que há o uso da classe CSS .screen-reader-text
juntamente com tags <span>
. Há duas abordagens diferentes nesta solução:
- no caso de descrições que complementam o que está na tela, como
De R$ 60,00
ePor R$ 48,00
, adicionamos um<span>
no meio do parágrafo. - por outro lado, quando a descrição é muito diferente do texto visível, usamos o atributo
aria-hidden='true'
nas tags<p>
(que “esconde” o elemento do leitor de tela, fazendo com que ele o ignore) e adicionamos o texto mais descritivo diretamente num<span>
, como em<span class='screen-reader-text'>em até 12 vezes de R$ 4,00 sem juros. </span>
.
Assim, segue a nova leitura feita pelo NVDA:
Transcrição do áudio: “Frame. Figura. Origami Tsuru Colorido (Um unid). De sessenta reais por quarenta e oito reais, em até doze vezes de quatro reais sem juros. Quantidade mínima: dez. Frete grátis. Legenda.”
Bem melhor agora! A descrição feita é mais inteligível e possui breves pausas entre os diferentes conteúdos do card (note a pontuação utilizada nas descrições, elas fazem diferença na leitura!).
Entendendo a solução
A solução foi bem simples, mas por quê margin
negativa? Qual a necessidade do clip
e do clip-path
? O artigo do WordPress mencionado no início da seção anterior explica melhor tudo isso, mas se você tem dificuldades com inglês, segue aqui uma tradução:
- O valor
width
eheight
é1px
pois alguns leitores de tela não leem elementos de tamanho0px
;margin: -1px;
esconde o elemento completamente;word-wrap: normal;
evita que o leitor de tela leia um texto letra por letra, dado que o texto está contido num espaço de apenas 1 pixel. Muitas combinações de leitores de tela e browsers leem palavras quebradas da forma como elas são dispostas visualmente;clip
está depreciado, mas foi adicionado para manter suporte a browsers mais antigos que ainda não suportamclip-path
.Nota:
display: none;
evisibility: hidden;
escondem o texto da tela, mas também o escondem dos leitores de tela. Assim, estes atributos não podem ser utilizados para dar descrições adicionais a usuários de screen readers.
Ressalto que a classe disponibilizada pelo WordPress tem como objetivo funcionar no máximo de combinações browser-leitor de tela. Caso esta não seja sua situação, algo do como:
.visually-hidden {
clip: rect(0.1rem, 0.1rem, 0.1rem, 0.1rem);
height: 0.1rem;
overflow: hidden;
position: absolute !important;
width: 0.1rem;
}
Também funciona. E vale lembrar que você pode alterar o nome da classe para o que achar que faz mais sentido!
Eai, o que achou? Já tinha ouvido um leitor de tela antes? Este post te ajudou a resolver seu problema? Conhece outra solução? Deixe nos comentários!
Obrigado por ler meu primeiro post no blog :) Espero escrever mais em breve!