Seu menu dropdown funciona com o teclado?

Uma das coisas mais importantes ao se tornar um site acessível é assegurar-se de que é possível navegar integralmente pelo site e acessar qualquer informação usando o teclado.

E isso não beneficia apenas os cegos, usuários de leitores de tela, como muitos pensam. Muitos grupos de usuários têm dificuldades sérias ou total impossibilidade de usar o mouse. Além dos cegos, pessoas com problemas de coordenação motora, mal de parkinson, paralisia cerebral, e até mesmo usuários de alguns dispositivos móveis. Isso para citar apenas alguns.

Juntando-se esses grupos, temos uma quantidade muito grande de usuários e clientes em potencial — idosos, por exemplo, entram em alguns desses grupos, e estão em número cada vez maior — que podem estar deixando de comprar seu produto ou consumir a informação que você publica porque seu site requer o uso do mouse para funcionar de maneira satisfatória.

Um recurso que frequentemente causa problemas áqueles que não podem — ou até mesmo não querem, por que não? — usar o mouse são os famosos menus dropdown.

A maioria das técnicas para criação de menus dropdowns hoje em dia usa apenas CSS para os browsers de verdade e um pouquinho de JavaScript para o IE6. Técnicas como a suckerfish, por exemplo, muito popular, por ser simples e por ter sido publicada no A List Apart, funcionam dessa maneira.

Basicamente, criamos listas não-ordenadas aninhadas. Ou seja, um submenu é marcado como uma lista dentro de um item de lista. Esses submenus são escondidos via CSS e só são exibidos quando se passa o mouse por cima do item de menu que o contém.

<ul id="menu">
<li><a href="/">Início</a></li>
<li><a href="/servicos">Serviços</a>
<ul>
<li><a href="/servicos/design">Design</a></li>
<li><a href="/servicos/prog">Programação</a></li>
</ul>
</li>
</ul>

Este código acima representa a marcação típica de um menu dropdown moderno. O CSS, sem grandes formatações seria mais ou menos assim:

ul{ list-style:none; }
#menu li {
float:left;
position:relative;
}
#menu li ul {
display:none;
position:absolute;
top:0.9em;
left:0;
margin:0;
padding:0;
}
#menu li:hover ul { display:block; }

Este código criaria um menu dropdow funcional (feio demais, mas funcional) nos browsers mais modernos, como Firefox, Opera, Safari e IE7. Como já disse, para o IE6 seria necessário um pouco de JavaScript, mas não vou colocar isso aqui. Vejam o suckerfish para entender como funciona.

O que nos importa aqui é o fato de que este menu dropdown é funcional apenas se o usuário estiver usando um mouse. Além do submenu nunca ser exibido para aqueles que estão navegando com o teclado, os itens desse submenu são removidos do índice de tabulação (tabindex) da página e nunca se chega a eles usando a tecla tab (ou qualquer outro recurso).

Mas, como resolver isso, você me pergunta. Bem, usando apenas HTML e CSS, creio que não haja nenhuma solução. Pelo menos não que eu conheça (se conhecer alguma, me conte, por favor).

Porém, usando-se JavaScript, é possível fazer com que os submenus sejam exibidos usando-se apenas o teclado.

Você pode querer argumentar que, ora, estamos falando de acessibilidade, como você vem agora querer me enfiar um JavaScript goela abaixo? O fato é que, na maioria das situações onde esse menu ficaria inacessível via teclado, o usuário tem o JavaScript habilitado no browser.

Pense comigo, só vamos ter problemas caso o browser do cara tenha suporte a CSS. Ou seja, estamos falando de browsers gráficos. São muito poucos os casos onde há suporte a CSS e não há suporte a JavaScript. Isso, praticamente, só ocorre quando o usuário deliberadamente desabilita o JavaScript ou usa o modo de segurança alta do IE, por exemplo.

Browsers de texto (lynx ou webvox, por exemplo) vão sempre exibir os submenus, por motivos óbvios. Dispositivos móveis, salvo raras excessões, não vão interpretar a propriedade display do CSS, portanto, também vão exibir os submenus.

Sendo assim, podemos usar o JavaScript como recurso para habilitar o uso dos menus dropdown para a quase totalidade de nossos usuários. Lembrem-se, 100% é apenas uma meta, raramente (praticamente nunca, na verdade) factível.

Como seria esse script? Bem, se não houvesse o IE (e estou falando do IE7 também, neste caso), seria muito, muito simples. Algo assim:

<script type="text/javascript">
var lis = document.getElementsByTagName('li');
for (var i = 0, li; li = lis[i]; i++){
li.onfocus = function(){
var ul = this.getElementsByTagName('ul')[0];
if (ul)
ul.style.display = 'block';
}
li.onblur = function(){
var ul = this.getElementsByTagName('ul')[0];
if (ul)
ul.style.display = '';
}
}
</script>

Ou seja, quando uma LI que contiver uma UL receber o foco, o submenu é exibido. Ao perder o foco, o menu é escondido novamente. Simples, não? Porém, o IE existe e é o líder do mercado, e é usado por grande parte dos usuários de leitores de tela também. Portanto, esse script só resolve uma parte do problema.

No IE não há o evento onfocus para itens de lista. Portanto, para que nosso menu funcione no IE — e, claro, continue funcionando nos outros browsers –, precisamos fazer com que o submenu apareça quando o link do item do menu de primeiro nível receber o foco e que desapareça quando o último link do submenu perder o foco. Vejam:

<script type="text/javascript">
var lis = document.getElementsByTagName('li');
for (var i = 0, li; li = lis[i]; i++){
var link = li.getElementsByTagName('a')[0];
if (link){
link.onfocus = function(){
var ul = this.parentNode.getElementsByTagName('ul')[0];
if (ul)
ul.style.display = 'block';
}
var ul = link.parentNode.getElementsByTagName('ul')[0];
if (ul){
var ullinks = ul.getElementsByTagName('a');
var ullinksqty = ullinks.length;
var lastItem = ullinks[ullinksqty - 1];
if (lastItem){
lastItem.onblur = function(){
this.parentNode.parentNode.style.display = 'none';
}
lastItem.parentNode.onblur = function(){
this.parentNode.style.display = '';
}
}
}
}
}
</script>

Sim, o código está longe de ser elegante, mas você pode melhorá-lo na hora da implementação. O fato é que funciona.

Vejam um exemplo (com um pouquinho a mais de CSS pra melhorar levemente a aparência).

Com uma medida muito simples, conseguimos melhorar a experiência de uso de nossos sites para um número bastante grande de usuários. Agora você não tem mais motivo para dizer que seu submenu não funciona com o teclado. Vamos lá, é muito simples pra você deixar de fazer.

Há uma implementação de menus dropdown completamente acessível feita pelo Brothercake. Chama-se Ultimate Dropdown menu e é bem completo, suporta vários níveis de menu, etc. Vale a pena conferir.

Conhece uma maneira mais fácil de fazer a mesma coisa? Achou algum erro no meu código? Vamos conversar.

PS: A falta de identação nos códigos de exemplo é cortesia do Zoundry (que é excelente, apesar desse pequeno problema). Alguém aí sabe como fazer essa identação? Não, a identação que ele tem, usando blockquote não serve.

22 Comentários sobre “Seu menu dropdown funciona com o teclado?”

Faça um comentário

#1 | Micox

O meu não funciona. 🙁
Script interessante. Não funcionou o shift+tab para voltar ao item anterior, mas o script não deixa de ser uma evolução.

Talvez em algumas implementações a pseudo class focus ajude em algo, não sei.


Bruno, muito boa a matéria, parabéns pela iniciativa! é muito importante a preocupação! Eu uso o framework Behaviour (http://bennolan.com/behaviour/), pra separar a camada de comportamento – sugiro que você dê uma olhada, e, quem sabe, escreva o que pensa a respeito aqui. Adicionando o onfocus/onblur, deu certo.
Acho ótima a preocupação.
Pra mim, o shift+tab funcionou… enfrentei foi um probleminha com o focus + onmouseover, abrindo dois submenus…
Grande abraço,
André.


#3 | João David

Olá Bruno

O tab funciona, não abre o submenu, mas posso navegar entre os itens do menu. Certo ?


#4 | João David

Olá novamente

http://www.farcrycms.org/

Este site no link acima utiliza um template chamado mollio:

http://www.mollio.org/

Este template usa o menu discutido, ele implementa o menu bem simples, arroz com feijão mesmo.

Como tab eu não consigo ver o submenu, mas conisgo “passear” pelos itens do menu principal e o menu secundário. Isso pode ser notado pela barra de status que exibe o endereço do link que está com o foco.

Bem é isso.


Interessante. Ele usa text-indent negativo. Não tinha pensado nisso.
Bom, pelo menos acho que o meu esquema ainda pode servir para algumas pessoas, porque vai funcionar em menus já existentes. É só jogar o script.
Depois escrevo algo mais sobre isso.


#6 | tigo

Legal Bruno.
É bom ler posts como este onde pode se ver um pouco de código.
Valeu.


Show de bola Bruno,

Pode até parecer exagero, mas qualquer um de nós pode, em determinada situação, ficar impossibilitado mesmo que temporariamente, de usar o mouse.

Um braço quebrado, uma tendinite, um óculos danificado, o mouse sujo, ou ainda, a necessidade de usar um determinado dispositivo com limitações. Por estas e outras tantas razões, não poderemos utilizar o mouse com precisão, ou simplesmente, não poderemos usar o mouse, sendo a única saída então o teclado.

Outro argumento, é que alguns usuários preferem usar o teclado ao mouse, então por que não aplicar o acesso ao menu dropdown também via teclado para que esse usuário tenha a liberdade de decidir como quer acessar?

Saltos (links internos) para o conteúdo principal, sistema de busca e menu interno, quando aplicados no início das páginas ou em alguns outros lugares estratégicos, dependendo da ocasião, aumentam bastante a usabilidade dos sites para quem usa apenas o teclado, mas isso é assunto para outro post.

Abraços


Aqui funcionou certinho, só faltou uma coisa que você esqueceu de incluir, logo no finalzinho do JS;

this.parentNode.parentNode.style.display = '';
Tem que ter o “none” ali, se não, o menu não desaparece quando você sai do link.
this.parentNode.parentNode.style.display = 'none';

Funcionou no IE e no Firefox, mas no Opera não navega com TAB, ou eu não configurei direito aqui. Hehe

Té! =)


#9 | Rafael Oliveira

Er, esquece a besteira que eu falei aí em cima. O que o Bruno postou tá certinho, se fizer o que falei ele para de funcionar. =X

Té, =)


#10 | Rubens A. Filho

Muito bom esses artigos sobre acessibilidade, estou entrando em um projeto e seus artigos estão sendo bem úteis.

Estava vendo o que o João disse, o menu feito com o método do suckerfish funciona do mesmo jeito que o do mollio.

Funcionar ele funciona, mas não acho “funcional” se é que me entendem… como disseram, alguem que enxerga pode não estar usando o mouse e ser um usuário mais que leigo e não olha para a barra de status. Sendo assim ele não vai ter noção de onde ele está e pra onde vai.

Essa atualização do js que o Bruno fez ficou bem funcional pra ambos.

obs: o shift+tab só não funcionou quando você está no ultimo link do menu

abraços


#11 | ubirajara

Jé tentou usar a tag para manter a identação do texto?


Olá Bruno, parabéns pelo artigo e pela participação no Acesso Digital. É dessas iniciativas que precisamos para evoluir nossos sites.
Sobre o script, ficou bem legal e simples de implementar. Só encontrei um problema. Ao passar pelo menu funciona tranquilo. Só que ao voltar na navegação com SHIFT+TAB os menus ficam abertos.

Vou tentar pensar em algo para solucionar isso. Se eu achar algo, coloco aqui.

Abraço!


#13 | YUri

Bruno,

O menu não funciona via mouse no IE6, vê se pode!?

Dá uma olhada!


#14 | solange

o que é Drop-down?


#15 | Marcel

Olá Bruno.

Muito massa o código, mas ele funcionou só parcialmente no meu menu.

Quando ele funciona no IE 6, atrapalha no 7, e vice-versa.

Mas obrigado.


#16 | TIAGO HEINECK

Bruno..

e pra funcionar no IE qdo passa o mouse em cima?


Muito bom o código.


#18 | alex

massa gostei muito…


#19 | Rodrigo

Lanço um desafio, o que vc alteraria se o menu tivesse 3 niveis.


#20 | Kandrad

Muito bacana este menu.
Você já deve ter visto uns menus com vários níveis(sub-menu).
Quando você abre um sub-menu do menu principal e este menu esta perto ao canto inferior da tela(imaginando que o menu esteja na posição vertical do lado esquerdo da tela), o menu (não sei como!) ao inves de rolar a tela para baixo para poder conter todo o sub-menu exibe este submenu para cima, para poder conter todo o menu na mesma tela!
Você sabe como isto é feito? Onde posso encontrar informações a respeito disso?

Muito obrigado pela atenção!
Kandrad


[…] Para ler o artigo original basta clicar aqui […]


Muito bom e seu post!

ho sobre a identação, vc coloca a tag pre essa tag tem a função de deixar o texto escrito como vc digitar, fica com espaço de tab e tudo mais.

no meu blogfolio, eu uso a e escrevo o exemplo de codigo dentro

abração e espero ter te ajudado 😉


«

»

Deixe seu comentário


  • Fatal error: Call to undefined function challenge_form() in /var/www/html/brunotorres.net/web/wp-content/themes/bt2008_wide/comments.php on line 65