Read in english (Automatic translation wiht Google) Todas as técnicas para reduzir o tempo de exibição de uma página são importantes. Uma das melhores formas de fazer isto é diminuindo o número de requisições HTTP e uma boa técnica para atingir este resultado é usando CSS-Sprite ou estampas em css. Neste tutorial nós iremos enisnar como criar um menu horizontal usando este conceito.

Passo 1

Ao contrário que muita gente pensa, pesquisas compravam que 80% do tempo gasto para exibir uma página está no front-end (High Performance Web Sites é um livro muito importante no assunto performance). Podemos reduzir este tempo de renderização quando temos menos requisições HTTP, o que significa um menor número de arquivos CSS,JS and outros recursos como imagens. Mas a questão é, como reduzir o número de imagens sem perder em design? CSS-Sprite é uma boa opção. Nosso primeiro passo é cortar o menu em uma grande com todos os estados possíveis nesta mesma imagem. Após o designer criar o layout o primeiro passo é avaliar o que temos.

Passo 2

Se olharmos com cuidado nós podemos ver que temos as abas com foco e sem foco, o que significa 6 arquivos de imagens, 1 arquivo para cada esta de hover e normal. Mas com CSS-Sprite nós podemos reduzir de 6 para apenas 1, isso irá reduiz o número de requisições e melhorar a performance no front-end. Corte seu menu como abaixo:

Passo 3

No passo 2 nós criamos a estampa de nosso menu (uma única imagem com todos os estados possível, neste caso apenas normal e hover). Agora é hora de pularmos para o XHTML e CSS. Precisamos criar um simples arquivo XHTML com um div para o cabeçalho, como abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CSS-Sprite</title>
<link rel="stylesheet" href="application.css"/>
</head>

<body>
  <div id="header_wrapper"></div>
</body>
</html>  

Passo 4

Agora precisamos criar o arquivo application.css. Em nosso css configuramos o TypeSelector body com background-color e criamos um IdSelector chamado de #header_wrapper, este seletor terá as propriedades como background-image, width de 100% e height de 90px.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

@charset "utf-8";
/* CSS Document */

body{
  background-color:#f0eee1;
  margin:0;
  padding:0;
}

#header_wrapper{
  background:url(images/header_bg.jpg) repeat-x;
  height:90px;
  width:100%;
}  

Passo 5

Agora é hora de criar o div chamado header, esse cara será o container para centralizar o conteúdo, neste caso, o container menu. Para centralizar o cabeçalho nós usamos "margin: 0 auto;" no seletor #header. Isso significa que noso header terá 0 de margin top e todos os outras margens serão calculadas automaticamente, outro detalhe importante é a altura e largura. Nosso HTML e CSS estarão como abaixo:

index.html
1
2
3
4
5
6
7
8

<body>
  <div id="header_wrapper">
    <div id="header">
      <img src="images/logo.jpg"/>
    </div>
  </div>
</body>
application.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@charset "utf-8";
/* CSS Document */

body{
  background-color:#f0eee1;
  margin:0;
  padding:0;
}

#header_wrapper{
  background:url(images/header_bg.jpg) repeat-x;
  height:90px;
  width:100%;
}

#header{
  margin:0 auto;
  width:760px;
}


#header img{float:left;} /*image of logo will be left aligned*/

Passo 6

Finalmente o passo de criação do menu. Primeiro precisamos criar um div para o menu, setamos o id para "menu". Agora colocamos uma tag "ul" (unordered list) dentro da div "menu", essa tag irá criar o efeito horizontal que desejamos. No css nós criamos o seletor para o menu, como abaixo:

application.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

@charset "utf-8";
/* CSS Document */

body{
  background-color:#f0eee1;
  margin:0;
  padding:0;
}

#header_wrapper{
  background:url(images/header_bg.jpg) repeat-x;
  height:90px;
  width:100%;
}

#header{
  margin:0 auto;
  width:760px;
}

#menu ul { width:300px; height:90px; margin:0 auto; padding: 0; list-style-type: none;}
#menu li {float: left; display: inline;}
#menu a {text-decoration: none;}
#menu span {display:none;}

Acima especificamos a tag "ul" dentro "#menu" que irá conter 300px de width(largura total do menu), 90px de altura(height) e também definimos "list-style-type" do "ul" para "none", o que garante que nosso "ul" não terá nenhum disco(bullet) para o itens. Com "#menu li" to os items da lista(tag "li") serão mostrados inline e alinhados a esquerda. Para finalizar esse passo vamos remover a decoração do links passando "nome" para text-decorantio do TypeSelector "a" e esconder o que tivermos dentro das tags "span".

Passo 7

Now is time to create "li's" and "a" inside ul, like below:

1
2
3
4
5
6
7
8
9
10
11

    <div id="header">
      <img src="images/logo.jpg"/>
      <div id="menu">
        <ul>
          <li><a href="#" class="home"><span>HOME</span></a></li>
          <li><a href="#" class="projects"><span>PROJECTS</span></a></li>
          <li><a href="#" class="contact"><span>CONTACT</span></a></li>
        </ul>
      </div>              
    </div>  

Passo 8

Neste passo começa o segredo do css-sprite. Nós usamos a mesma imagem para criar o fundo de cada item do menu. Veja o código css abaixo:

1
2
3
4

#menu a.home {width: 101px; height: 90px; background:url(images/menu.jpg) 0px 0px no-repeat;}
#menu a.home:hover {background:url(images/menu.jpg) 0px -90px no-repeat;}
#menu li.current a.home {background:url(images/menu.jpg) 0px -90px no-repeat;}  

O código acima representa que quando tivermos um "a" do "menu" e a div tenha a classe "home" ele terá o tamanho de 101x91 pixels e background-image("images/menu.jpg") será posicionado em 0 X da imagem de fundo e 0 Y da imagem de fundo, respectivamente . Mas se você olhar em a.home:hover e li.current the background a posição da imagem em y e -90, o que garante que nossa imagem será posicionada na parte do estado de hover em nossa estampa.

Passo 9

Repita o passo anterior para o restante do menu mas recalculando a posição da imagem de fundo, como abaixo:

1
2
3
4
5
6
7
8

#menu a.projects {width: 100px; height: 90px; background:url(images/menu.jpg) -100px 0px no-repeat;}
#menu a.projects:hover {background:url(images/menu.jpg) -100px -90px no-repeat;}
#menu li.current a.projects {background:url(images/menu.jpg) -100px -90px no-repeat;}

#menu a.contact {width: 101px; height: 90px; background:url(images/menu.jpg) -200px 0px no-repeat;}
#menu a.contact:hover {background:url(images/menu.jpg) -200px -90px no-repeat;}
#menu li.current a.contact {background:url(images/menu.jpg) -200px -90px no-repeat;}  

Passo 10

Nosso arquivo html e css finais serão assim:

index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CSS-Sprite</title>
<link rel="stylesheet" href="application.css"/>
</head>

<body>
    <div id="header_wrapper">
    <div id="header">
      <img src="images/logo.jpg"/>
      <div id="menu">
        <ul>
          <li class="current"><a href="#" class="home"><span>HOME</span></a></li>
          <li><a href="#" class="projects"><span>PROJECTS</span></a></li>
          <li><a href="#" class="contact"><span>CONTACT</span></a></li>
        </ul>
      </div>              
    </div>
  </div>
</body>
</html>
application.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

@charset "utf-8";
/* CSS Document */

body{
  background-color:#f0eee1;
  margin:0;
  padding:0;
}

#header_wrapper{
  background:url(images/header_bg.jpg) repeat-x;
  height:90px;
  width:100%;
}

#header{
  margin:0 auto;
  width:760px;
}

#header img{float:left;}

/*** MENU ***/
#menu {height:90px; float:right;}
#menu ul {  margin:0 ; padding: 0; list-style-type: none;}
#menu li {float: left; display: inline;}
#menu a {float: left; display: inline; text-decoration: none;}
#menu span{display:none;}

/* MENU - HOME */
#menu a.home {width: 101px; height: 90px; background:url(images/menu.jpg) 0px 0px no-repeat;}
#menu a.home:hover {background:url(images/menu.jpg) 0px -90px no-repeat;}
#menu li.current a.home {background:url(images/menu.jpg) 0px -90px no-repeat;}

/* MENU - PROJECTS */
#menu a.projects {width: 100px; height: 90px; background:url(images/menu.jpg) -100px 0px no-repeat;}
#menu a.projects:hover {background:url(images/menu.jpg) -100px -90px no-repeat;}
#menu li.current a.projects {background:url(images/menu.jpg) -100px -90px no-repeat;}

/* MENU - CONTACT */
#menu a.contact {width: 101px; height: 90px; background:url(images/menu.jpg) -200px 0px no-repeat;}
#menu a.contact:hover {background:url(images/menu.jpg) -200px -90px no-repeat;}
#menu li.current a.contact {background:url(images/menu.jpg) -200px -90px no-repeat;}

Conclusão

Do ponto de vista de perfomance podemos reduzir ainda mais nosso css utilizando compressão e reduzindo espaços e tags desnecessárias mas o objetivo final do tutorial e ensinar como utilizar a técnica de CSS-Sprite para criar menus. Com menos de 11 passos nós reduzimos drasticamente o número de imagens e consequentemente o número de requisições HTTP, essa técnica pode ser usada em qualquer outro grupo de imagens como ícones ou botões. Para reforcar a estudo sobre o tema de performance em front-end leia o livro "High Performance Web Sites" book.
. Espero que tenham gostado da dica.

DOWNLOAD DOS ARQUIVOS DE EXAMPLO

Desculpe, comentários estão fechados para este artigo.