Voltando à ativa depois de tanto tempo de inatividade, quero mostrar a vocês um exemplo comum de uso das camadas de conteúdo e apresentação. Um menu com imagens e rollover, mais acessível do que o normal e não muito complicado de se fazer.
O conceito é bastante simples: um DIV contendo uma lista não ordenada (UL), cujos itens são posicionados de maneira absoluta, funcionando mais ou menos como um mapa de imagens (MAP). O rollover é obtido mudando o posicionamento da imagem de fundo. No final, vou mostrar algumas modificações que podem ser usadas para tornar o menu mais acessível.
Vamos começar do começo, como sempre:
Código HTML básico
<div id="menu">
<ul>
<li><a href="#">Início</a></li>
<li><a href="#">Artigos</a></li>
<li><a href="#">Contato</a></li>
</ul>
</div>
O código acima é praticamente tudo que vamos precisar ter na camada de conteúdo. Bem simples, como deve ser. Veja o exemplo 1.
Posicionando o que tem que ser posicionado
<style type="text/css">
#menu{ position:relative; width:186px; height:35px; }
#menu ul{ list-style:none; }
#menu li{
position:absolute;
top:0;
height:35px;
border:1px solid;
}
#menu li a{
display:block;
width:100%;
height:100%;
top:0;
}
#um{ width:53px; left:0; }
#dois{ width:61px; left:53px; }
#tres{ width:72px; left:114px; }
</style>
<div id="menu">
<ul>
<li id="um"><a href="#">Início</a></li>
<li id="dois"><a href="#">Artigos</a></li>
<li id="tres"><a href="#">Contato</a></li>
</ul>
</div>
Adicionamos um ID para cada item da lista, para que suas posições e larguras possam ser definidos separadamente.
O DIV menu precisa ter posicionamento relativo, para “conter” seus filhos, que serão posicionados de maneira absoluta. (leia meu artigo sobre posicionamento com CSS)
Note que cada LI tem uma largura (width) e uma posição horizontal (left) diferentes. O cálculo é simples: o valor de left é sempre a largura do LI anterior somado ao valor de left deste.
Usamos uma borda apenas para ilustrar. Veja o resultado no exemplo 2.
Adicionando uma imagem de fundo
A imagem de fundo deve ser o menu inteiro. Algo mais ou menos como a imagem abaixo:

Esta imagem vai ser aplicada como fundo do DIV menu. E esta é a única mudança com relação ao exemplo anterior:
#menu{
position:relative;
width:186px;
height:35px;
background:url(img1.gif) no-repeat 0 0;
}
Veja o resultado no exemplo 3. Note que o texto está por cima da imagem. Vamos resolver isso.
Escondendo o texto
A forma mais simples de esconder o texto é usando a propriedade CSS text-indent com um valor negativo muito alto. Vamos usar -9999em. Isso faz com que o texto seja levado para a esquerda e fique fora do espaço visível.
Esta técnica tem sido muito usada para efeitos de image replacement, que é como chamamos os métodos usados para substituir texto por imagens, usando CSS.
Este método, usando text-indent negativo, é efetivo, porém tem o problema de não exibir conteúdo algum caso o browser tenha suporte a CSS ligado e suporte a imagens desligado. Esta é uma situação bem difícil de acontecer, mas nem por isso devemos deixar de nos preocupar. Vamos achar uma maneira de resolver este problema no último passo do tutorial.
O que muda no código:
#menu ul{
list-style:none;
text-indent:-9999em;
}
#menu li a{
display:block;
text-decoration:none;
width:100%;
height:100%;
top:0;
}
O text-indent negativo foi aplicado ao UL e colocamos um text-decoration:none no A, para evitar que apareça uma linha azul estranhíssima em algumas versões do IE.
Veja o resultado no exemplo 4.
Adicionando o efeito de rollover
Para obter o efeito de rollover (ou seja, alguma mudança ao se passar o mouse sobre o elemento), vamos mudar a imagem usada como fundo. Apenas duplicamos a imagem e mudamos alguma coisa em cada um do itens. Neste caso, mudei a cor do texto. Veja:

Mesmo a imagem tendo o dobro da altura da anterior, apenas a parte superior vai aparecer, já que nosso DIV tem uma altura fixa, em pixels.
Para o rollover, vamos usar a pseudo-classe :hover do A, e aplicar a imagem acima como fundo deste elemento, porém em posições diferentes para cada um deles. Veja:
#um a:hover{
background:url(img2.gif) no-repeat 0 -35px;
}
#dois a:hover{
background:url(img2.gif) no-repeat -53px -35px;
}
#tres a:hover{
background:url(img2.gif) no-repeat -114px -35px;
}
O primeiro valor é a posição da imagem na horizontal (left) e o segundo, na vertical (top). Percebam que o primeiro valor é sempre igual ao left do LI que contém o A. Veja o exemplo 5.
Um pouco mais de acessibilidade
Lembra do que falei, lá em cima, sobre nada ser exibido caso tenhamos CSS habilitado e imagens desabilitadas? Pois bem, há uma solução. Mas, claro, não é de graça. Vamos ter que adicionar alguma coisa ao nosso código HTML.
<div id="menu">
<ul>
<li id="um"><a href="#"><span></span>Início</a></li>
<li id="dois"><a href="#"><span></span>Artigos</a></li>
<li id="tres"><a href="#"><span></span>Contato</a></li>
</ul>
</div>
Colocamos um SPAN vazio dentro de cada A. Alguns podem achar isso um pouco “sujo” e, na verdade, não deixa de ser. Porém, não perdemos nada de substancial com o uso destes elementos vazios, e vamos, no entanto, ganhar um pouco em termos de acessibilidade. Na minha opinião, vale a pena. Você decide se vale ou não para você.
Os referidos SPANs vão ser declarados como elementos de bloco e posicionados de maneira absoluta, de modo que fiquem “por cima” de seus pais (A). Vamos colocar uma imagem de fundo para cada SPAN (o mesmo valor usado nos :hovers, mas com posição vertical 0 ao invés de -35px). Veja:
#menu li a span{
display:block;
position:absolute;
width:100%;
height:100%;
top:0;
cursor:pointer;
}
#um a span{
background:url(img2.gif) no-repeat 0 0;
}
#dois a span{
background:url(img2.gif) no-repeat -53px 0;
}
#tres a span{
background:url(img2.gif) no-repeat -114px 0;
}
Percebam que tive que usar cursor:pointer para que o cursor padrão de ponteiro (aquela “mãozinha” que aparece quando você passa o mouse sobre um link) apareça no Internet Explorer.
Vejam o exemplo 6.
Rollover de novo
Vamos adicionar o efeito de rollover a esse nosso novo código.
#um a:hover span{
background:url(img2.gif) no-repeat 0 -35px;
}
#dois a:hover span{
background:url(img2.gif) no-repeat -53px -35px;
}
#tres a:hover span{
background:url(img2.gif) no-repeat -114px -35px;
}
Se você acompanhou bem até aqui, acho que não preciso explicar, né? Vejam o exemplo 7.
Consertando o rollover no IE
Os mais atentos com certeza notaram que ocorre um problema com o exemplo acima no Internet Explorer. Quando você passa o mouse sobre um link, ele muda de cor, mas não volta à cor original quando o cursor é movido para fora do elemento. Não me perguntem por que isso acontece, não faço a mínima idéia.
Passei alguns minutos tentando achar uma solução, e achei!
Por algum motivo, se colocarmos o z-index (que é o posicionamento no eixo Z, ou seja, serve para colocar um elemento “por cima” de outro) do a:hover para um valor alto (vou usar 1000, que é o valor máximo), tudo passa a funcionar perfeitamente no IE, e continua funcionando normalmente nos outros browsers.
#menu ul li a:hover{
z-index:1000;
}
Simples assim. Porém, notem que o seletor desta regra deve ser mais específico que o do :hover. Vou falar sobre especificidade um dia desses. Por agora, tente adicionar apenas um ID a mais no seletor (no caso #menu) e especificar cada um dos elementos, na ordem (no caso ul li). Isso vai funcionar.
Confira o resultado final.
O código foi testado e aprovado nos seguintes browsers:
- Firefox 1.5
- Opera 9
- Internet Explorer 6
- Swift (um “safari para windows”, muito experimental ainda, portanto não posso garantir que o resultado seja o mesmo no safari do Mac OS X).
Se algum de vocês puder testar em outros browsers e me dizer se funciona, agradeço.
***
Espero que este exemplo seja de alguma utilidade para vocês. Dúvidas, sugestões e reclamações são muito bem vindas.
setembro 4th, 2006 at 11:33 am
Bem legal o Tuto, muito boa as dicas!!!
setembro 4th, 2006 at 10:20 pm
Muito bom…
Mas porque diabos uma span vazia?
Eu entendi o motivo de ela estar ali, mas não consegui entender o porquê de, mesmo estando ela vazia, o texto continuar aparecendo ao desabilitar as imagens…
setembro 5th, 2006 at 12:24 am
Jader, o span é usado apenas pra receber uma imagem de fundo.
ele fica dentro do A, antes do texto. Quando voce coloca ele como position:absolute, display:block e da as dimensões corretas, automaticamente ele fica “por cima” desse texto.
Quando você desabilita as imagens, o texto aparece porque ele estava simplesmente “por trás da imagem”, e não escondido de verdade.
setembro 7th, 2006 at 10:03 pm
Muito bom mesmo.
outubro 5th, 2006 at 4:58 pm
Oi.. Gostaria de saber como posso fazer um menu dessa maneira se ele for na vertical? Adorei esse estilo na horizontal e queria fazer na vertical.
Obrigado
outubro 11th, 2006 at 5:26 pm
Muito bom mesmo… infelizmente o IE sempre dando dor de cabeça. Vamos esperar o IE7 para ver.
fevereiro 22nd, 2007 at 8:35 am
olá …gostaria de saber como
faço para inserir e configurar
um formMail no meu site
eu tentei colocar …mas não deu certo
eu quero que os post’s vão direto
para o meu e-mail sem que seja
aberto o outlook
…
vlw
março 1st, 2007 at 5:04 pm
Como faço para usar somente texto, sem imagem. Ex.: Mouseover (texto normal) Mouse On (texto sublinhado)
março 3rd, 2007 at 9:33 am
muito bom XD
março 26th, 2007 at 5:46 pm
http://www.sonhoseencantos.com.br/publique
Fiz sua rotina, mas o texto no mouse on, sobe, não fica alinhado no meio. Como fazer para alinha o texto no meio?!
Grato.,
Luiz Claudio
abril 1st, 2007 at 9:32 pm
Por acaso vc já utilizou essa técnica para fazer um menu com submenus???
Caso sim, gostaria de um exemplo!
Grato!!
abril 9th, 2007 at 3:21 pm
Esses codigos são muito dificeis de fazer, só consegui fazer meu menu até o exemplo 2, e depois não deu mais certo, o que queria mesmo é que este site tivesse um gerador de menus para as pessoas fazerem os seus e depois só era copiar o cod. do menu já pronto!!!
Estou muito chateado por não ter conseguido ter feito.
Nunca mais vou entrar neste site!
maio 7th, 2007 at 12:32 pm
Opá.. ótimo tutorial !!
Congratulation..
[]´s
maio 16th, 2007 at 5:41 pm
[...] em particular a possibilidade de substituir imagens quando o mouse passasse por cima do gif dando o efeito rollover, que antes eu fazia através de um gerador automático de código javascript que se juntava ao HTML [...]
setembro 8th, 2007 at 1:19 am
Beleza Pessoal?
No IE 7 está perfeito, porém no Firefox 2.0.0.6 não faz o efeito rollover nem habilita o link.
Abs
Marcos
outubro 7th, 2007 at 8:28 pm
[...] uma delas com seus prós e contras. Eu já usei uma dessas técnicas por aqui em um artigo sobre menus com imagens e rollover (que, a propósito, precisa de algumas atualizações e [...]
novembro 3rd, 2007 at 11:38 am
#um{ width:53px; left:0; }
#dois{ width:61px; left:53px; }
#tres{ width:72px; left:114px; }
ESTOU ME ATRAPALHANDO NESSA PARTE AÍ
—- PORQUE EU QUERO COLOCAR OITO… TUDO BEM EU COLOKO .. MAS NÃO ENTENDI ESSES TAMANHOS AÍ NÃO..SAI TUDO ERRADO UM POR CIMA DO OUTRO… ALGUEM ME AJUDA POR FAVOR —–
novembro 7th, 2007 at 6:01 pm
Sou iniciante por aqui, por isso minha dúvida é trivial.
Quais comandos utilizo para colocar uma imagem como plano de fundo com uma mensagem inserida.
Obrigada.
Gláucia P. MAciel
dezembro 7th, 2007 at 2:11 am
Excelente Tutorial, funcionou perfeitamente no I.E. 6 e Firefox 2.0, parabéns pela iniciativa, o span também foi muito útil, pois concertou a seleção indesejada do Firefox.
O único fato que ficou em duvida, e de que o parte do span só funcionou no firefox, portanto, coloquei o primeiro código para o IE, e o do span para o firefox.
Você tem algum comentário sobre isso?
Parabéns e Até
Adriano
dezembro 30th, 2007 at 1:40 pm
Bruno, pra vc não é problema o fato de usar o e não validar o código?
Não acharia melhor usar
Texto
Colocaria no css display block para o A e aplicaria a como background nele.
Daí esconderia o span com display none.
O código ficaria validado.
outubro 8th, 2008 at 3:10 pm
muito interessante, gostei de sua forma didática e inteligente de agir..
Parabéns!
janeiro 16th, 2009 at 7:28 pm
Gostaria de saber se tem um limite do menu, pois estou utilizando 12 itens, mas ele funciona ate o 9 o restante fica com o texto em cima e nda de rolover, poderia me ajudar ??
julho 8th, 2009 at 1:29 pm
voce salvo minha pele cara
muitoo obrigado mesmo!!
valew
novembro 30th, 2009 at 11:45 pm
Bem,
Eu refiz o meu web site usando um meno neste estilo, ele funcionou perfeitamente no IE8 mas ao testar no Chrome e no firefox 3.5.3 o menu é replicado. então adicionei o seguinte:
#menu ul {
margin-top:-16px;
position:relative;}
ai ficou show funcionou corretamente nos dois, mas ao testar no IE7 tmb dá pau, o menu replica quase q um em cima do outro. Vc sabe como corrigir para IE7 tmb?
Valew, muito boa sua matéria está de parabéns!
março 24th, 2010 at 5:17 pm
Esse eu vou ter que comentar.
Estou começando a trabalhar com webdesign agora.
Fucei, fucei e fucei por tudo tentando achar uma forma de por um menu desses num site e não conseguia. Tentei de tudo e não dava certo. Até que eu achei esse tuto aqui.
Está perfeito agora. Do jeito que eu fiz no photoshop.
Muito obrigado mano, me ajudou muito.
abraços
junho 29th, 2010 at 2:57 pm
te amo, thanks
julho 6th, 2010 at 2:40 pm
Alguma chance de tu fazer esse menu na vertical…, já tirei e coloquei vários atributos e não consegui fazê-lo
grata
julho 13th, 2010 at 5:01 pm
Boa tarde, o meu não ficou na horizontal… e no firefox ficou la em baixo, em vez de no topo da pagina como no IE… pode me ajudar?
obrigada!
outubro 19th, 2010 at 2:43 am
Tremendous blog post, a bunch of good tips. I want to point out to my friend and ask them what they think.
março 19th, 2011 at 4:53 pm
Funciona também no google chrome!
abril 1st, 2011 at 9:03 am
Muito boa dica cara!Me ajudou bastante1
Valeu e continue assim!
julho 31st, 2011 at 5:05 pm
Good to be visiting your blog again, it has been months for me. Well that article that i’ve been waited for so long. I will need this article to complete my assignment in the college, and also it has same topic with your article. Thanks, great share.
novembro 9th, 2011 at 4:12 am
Valeu Bruno!
Funcional, claro e efetivo. A Web precisa de mais tutoriais assim.
Obrigado!