Otimizando um menu com a técnica de CSS sprite

Por Erika Sarti, em 15_04_2009.

Introdução

Imagine que você tem um menu totalmente baseado em imagens, e que quando o usuário do seu site passa o mouse sobre um dos itens essa imagem muda, como no exemplo abaixo:

Desenvolver este menu utilizando CSS (Cascading Style Sheets) ao invés de Flash é uma ótima opção, mas será que é preciso criar duas imagens para cada item, isto é, uma para cada "estado"? Na verdade, não. Utilizando a técnica conhecida como CSS sprite é possível aplicar apenas uma imagem para todo o menu, apenas inserindo, através de CSS, a imagem como fundo para cada elemento na posição correta. Você entenderá como fazer isso neste tutorial. Para tanto, espera-se que o leitor tenha conhecimentos básicos de HTML e CSS. Vamos lá?


Aplicando CSS sprite

Para este tutorial, vamos utilizar com base a seguinte imagem:

Imagem de abas para exemplo

Primeiro começamos com o menu em abas. O princípio é o mesmo do tutorial Menu em abas em CSS num layout tableless publicado aqui no Infowester (portanto, é recomendável lê-lo): usamos uma lista e, através de CSS, fazemos a modificação visual.

O código HTML dessa lista é:

<ul id="menu">
	<li><a href="#">Home</a></li>
	<li><a href="#">Sobre este site</a></li>
	<li><a href="#">Contato</a></li>
	</ul>

E o CSS para este trecho:

#menu			{loading="lazy" width: 460px; margin: 30px auto 100px; padding: 0;}

	#menu li		{display: inline;}

	#menu li a		{background: url(menu_css_sprite/menu.png); float: left; height: 40px;
				text-indent: -10000px; margin-right: 10px;}

Porém, apesar de todas as abas terem 40 pixels de altura, no nosso menu cada item tem uma largura diferente. Além disso, o "truque" do menu é usar CSS para posicionar a imagem como fundo de cada elemento individualmente, exibindo apenas o pedaço desejado. Assim, vamos adicionar uma classe para cada elemento do menu. Essa classe vai, através de CSS, determinar tanto a largura do elemento quanto o posicionamento da imagem de fundo.

No caso da aba "Home", usamos um editor de imagens para determinar largura e posicionamento:

Determinando largura e posicionamento de aba

Com essas informações, adicionamos ao nosso código HTML um class="home" e no nosso código CSS acrescentamos os parâmetros para esta classe:

<ul id="menu">
	<li><a class="home" href="#">Home</a></li>
	
#menu .home		{background-position: 0px 0px; loading="lazy" width: 110px;}

Agora, definiremos a posição da aba "Home" quando o visitante passar o mouse sobre ela:

Determinando largura e posicionamento de aba: segundo passo

#menu .home:hover	{background-position: 0px -40px; loading="lazy" width: 110px;}

Repetindo o mesmo procedimento para as outras abas, nosso HTML ficará assim:

<ul id="menu">
	<li><a class="home" href="#">Home</a></li>
	<li><a class="sobre" href="#">Sobre este site</a></li>
	<li><a class="contato" href="#">Contato</a></li>
	</ul>

E nosso CSS, já com as abas "Sobre este site" e "Contato" corretamente posicionadas e com a largura definida:

#menu .home		{background-position: 0px 0px; loading="lazy" width: 110px;}
	#menu .home:hover	{background-position: 0px -40px;}

	#menu .sobre		{background-position: -110px 0px; loading="lazy" width: 190px;}
	#menu .sobre:hover	{background-position: -110px -40px;}

	#menu .contato		{background-position: -300px 0px; loading="lazy" width: 130px;}
	#menu .contato:hover	{background-position: -300px -40px;}

Isso facilita bastante a atualização do site, pois em caso de mudança de layout será necessário editar apenas um arquivo com as imagens.


Finalizando

Talvez você tenha percebido que principal vantagem desta técnica é o ganho de velocidade no carregamento da página. Para cada imagem exibida numa página HTML é feita uma requisição ao servidor. Quando usamos CSS sprite, diminuimos a quantidade de requisições - no caso do nosso menu, é feita apenas uma requisição para o arquivo menu.png, ao invés de 6 requisições, uma para cada imagem em cada estado, caso elas estivessem separadas. Isso faz com que a página carregue mais rápido e o servidor fique menos sobrecarregado. Além disso, todas as imagens são carregadas ao mesmo tempo, o que evita aquele velho problema do visitante passar o mouse sobre um item do menu e a imagem do hover não aparecer imediatamente porque ainda não foi carregada.

É importante frisar que a técnica de CSS sprite pode ser usada em qualquer imagem da sua página HTML, não apenas no menu. O YouTube por exemplo, usa essa técnica para juntar todas as imagens do site em um único arquivo, o que faz com que o site seja bastante otimizado.


Erika Sarti é web designer e trabalha como free-lancer desde 2000, sendo também responsável pelo layout do Infowester. Mais informações em seu blog - www.erikasarti.com - e em seu portfólio - www.erikasarti.net -.