Navegação Em Abas Com CSS E jQuery

Organizar o conteúdo do website utilizando abas é uma solução elegante e conveniente. Ajuda a tornar a página mais organizada deixando o visual mais leve e objetivo.

Neste tutorial será criada uma navegação em abas utilizando CSS e jQuery. Vamos utilizar todo a potência dos seletores para simplificar o código.

navegação em abas

Concepção Do Menu Em Abas

Quando uma itens das abas for clicada, o script pegara o valor contido na propriedade href dele e vai encontrar uma div na página que tenha o mesmo valor para sua id. O conteúdo desta div será então inserido dentro da div responsável por mostrar as informações e a aba clicada ficara de cor diferente para informar que esta ativa.

Como você deve ter percebido o conteúdo já estará presente na página, mas oculto. Outra possibilidade é carregar os textos via requisições AJAX.

Estrutura Da Página



<div class="global-div">

<h1>Navegação em abas</h1>

<ul class="abas">
    <li><a href="#noticia1">Mercúrio</a></li>
    <li><a href="#noticia2">Vênus</a></li>
    <li><a href="#noticia3">Terra</a></li>
    <li><a href="#noticia4">Marte</a></li>
</ul>

<div id="noticia"></div>

<div id="conteudo">

<div id="noticia1">
    <h2>Título</h2>
    <p>info</p>
</div>

<div id="noticia2">
    <h2>Título</h2>
    <p>info</p>
</div>

<div id="noticia3">
    <h2>Título</h2>
    <p>info</p>
</div>

</div>

</div>

Como de praxe, os itens do menu-aba são criados utilizando lista. Encaixa-se logo abaixo a div que apresentará a informação, uma div para englobar todos os textos e as divs respectivas de cada texto com o mesmo valor de id definido que o href de cada link.

Formatação



ul{list-style:none; padding-left:10px;}

.abas li{float:left; border:1px solid #ccc; border-bottom:0; margin-right:10px; padding:10px; border-top-left-radius:5px; border-top-right-radius:5px; -moz-border-radius-topleft:5px; -moz-border-radius-topright:5px; -webkit-border-radius-topleft:5px; -webkit-border-radius-topright:5px; }

.abas li:hover{box-shadow:0 -2px 3px #DFDFDF; -moz-box-shadow:0 -2px 3px #DFDFDF; -webkit-box-shadow:0 -2px 3px #DFDFDF; font-weight:bold; border-color:#c0c0c0;}

.ativo{background:#ccc; border-color:#333;}

.ativo a{color:#fff; font-weight:bold; text-shadow:0 0 5px #999;}

#noticia{position:relative; width:880px; height:auto; padding:10px; clear:both; border:1px solid #ccc; -moz-box-shadow:0 -1px 3px #ccc;}

#noticia div{display:none;}

São retirados os marcadores padrão para itens da lista e criado um recuo para o conteúdo.

Em seguida os itens da lista são posicionados à esquerda neutralizando o comportamento padrão que é nível de bloco. Bordas são aplicadas criando os delimitadores, somente a de baixo é retirada. É aplicada margem e efeitos CSS 3 que funcionarão somente no Firefox e Chrome-Safari.

Quando o mouse passar sobre o item, um efeito de sombra aliado à fonte negritada destaca o item. E a borda é escurecida para criar definição. Alguns deste efeitos somente funcionam nos navegadores modernos. Seja pelo efeitos CSS 3 ou pelo estado :hover em um item de lista ao invés de um link.

A classe “ativo” formata o item clicado e informa ao usuário qual das abas ele esta vendo. E o link do item também é afetado.

Continuando, definimos o posicionamento e dimensão da div que recebe a notícia, o espaçamento interno, borda e sombra.

Por fim são ocultadas qualquer div dentro de “#notícia”. Se você voltar à estrutura verá que não existe div dentro de “#noticia”. Mas vamos inserir através do javascript.

Iniciando O Script

Sendo que utilizaremos jQuery, no cabeçalho do arquivo HTML, importe a biblioteca e também o arquivo que criaremos.



<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="javascript.js"></script>

Já no arquivo, a primeira linha servirá para esconder as divs do conteúdo. Por que não fazer isso através do CSS? Se o javascript não estiver habilitado o conteúdo será mostrado mesmo assim. Se fosse escondido com CSS e mostrado somente com javascript, o conteúdo não ficaria visível neste caso.



$(function(){
  $('#conteudo').hide();
})

Lendo O Hash

Em uma url, o que vier depois do sinal “#” é considerada a parte hash. Ela aparece quando utilizamos ancoras para navegar dentro do próprio documento. No caso das abas criadas, clique na primeira aba e observe que na barra de endereço aparece no final da url, “#noticia1”.

Alguém visitou a nossa página e considerou interessante a notícia da terceira aba e decidiu compartilhar o endereço. Quem receber a dica e tentar acessar a página verá a primeira aba e não a terceira como deveria ser. Este é um problema comum quando utilizamos o javascript para ocultar conteúdo. Vejamos como resolver.


var noticia;  
var hash = window.location.hash;
if (hash !='')
{
noticia = $(hash).html(); // se for passado index.htm#noticia3 ela devolve #noticia3
  $('.abas li a[href="' + hash + '"]').parent().addClass('ativo');    
}

O javascript disponibiliza de uma propriedade específica para capturar a parte hash da url que é depositada na variável “hash”.

Na linha de baixo é feita uma verificação para saber se a variável recebeu algum valor. Pois isso somente ira acontecer se a url passada já tiver uma aba como alvo.

Se a “hash” não estiver vazio, a variável “noticia” receberá o conteúdo HTML do elemento na página que tiver a id com o valor igual ao da “hash”.

Sendo assim, se a url for “index.htm#noticia2”, ao carregar a página, a variável “noticia” recebera o que estiver contido dentro da div com id “#noticia2”. O que inclui textos e marcação.

Como é necessário mudar a aparência do item da aba que foi “clicado”, na linha seguinte é feita a seleção do elemento. Ele procura pelo elemento com a classe “.abas” que tenha um item de lista englobando um link com o valor da propriedade href “#noticia2”. Encontrando o elemento, olha para o elemento-pai deste e adiciona a classe “ativo”.

Sem hash

Se a página for acessada normalmente, o conteúdo da primeira aba deve aparecer.



if (hash !='')
{
..
} else {
  noticia = $('#conteudo div:first-child').html();      
  $('.abas li:first-child').addClass('ativo');    
}

$('#noticia').append('<div>' + noticia + '</div>').find('div').slideDown();

Se a variável “hash” estiver vazia significa que a url é somente para a página então “noticia” recebe o conteúdo da primeira div existente após a abertura da div “#conteudo”. Assim como o primeiro item da aba recebe a classe “ativo”.

Até o momento, a notícia não esta visível na tela.

Para que fique visível, é anexada à div “#noticia” o conteúdo da variável “noticia” englobado por uma div. Isso é útil para facilitar a criação da animação. Estamos encadeando as ações, então após anexar o conteúdo, o script acha (find) dentro da div “#noticia” uma div, que foi inserida agora, e mostra ela com um efeito deslizante.

Escolhendo A Aba

Definimos o que acontece quando um dos links da aba for clicado.



$('.abas li a').click(function(){
  $('.abas li').removeClass('ativo');
  $(this).parent().addClass('ativo');
  var ancora = $(this).attr('href');
  var nome = ancora.substr(1, ancora.length);
  noticia = $('#conteudo div[id="' + nome + '"]').html();
  $('#noticia').empty();
  $('#noticia').append('<div>' + noticia + '</div>').find('div').slideDown();
return false();
})

Primeiro ele remove a classe “ativo” de todos os itens. Em seguida ele seleciona o elemento-pai (parent) do link clicado e adiciona a classe “ativo”. A variável “ancora” recebe o valor da propriedade href deste link e na linha seguinte é dividida para tirar o “#” da frente do nome.

A variável “noticia” recebe então o conteúdo da div que possuir o id igual ao valor do href do item clicado sem o sinal “#”. A div “noticia” é esvaziada e é inserido novo conteúdo. No final o return false evita que ao clicar no link a página role para o topo.

Conclusão

Apesar da abundância de plugins disponíveis para trabalhar com abas, desenvolver uma solução própria é a melhor opção. Você ganha controle sobre o comportamento, aprende e tem um arquivo extremamente leve.

Faça testes com este que criamos e divida seus resultados connosco.

Download do código utilizado neste tutorial: Navegação Em Abas Com CSS E jQuery

Be Sociable, Share!

26 Comentários

  1. Gabriel Morais

    muito bom. Me ajudou bastante!

  2. Cara, vc não imagina o problema que me resolveu. Valeuu mesmo!

  3. Olá, não está aparecendo o conteúdo. Alguém sabe o que pode ser? Obrigado e ótimo post.

  4. tatiani

    puts !!! amei vc me salvou mesmo…
    vc add sue blog nos meus preferidos

  5. João Fernandes

    usei ficou show de bola, mais quando adiciono um campo textbox e clico em um  botão qualquer ele coloca uma virgula no textbox e depois vai replicando. Obs: Estou usando Asp
    Ex: 
    1° clique no botão:  ele coloca virgula
    2° Clique no botão : ele vai replicando o conteudo do text box.

       Ex: .    ",50" vai ficar ",50,50"

    Mo doido vou ver se acho o erro, se alguem souber de algo posta ai?

  6. Jefferson Monteiro

    Show de bola, parabéns pelo post!

  7. valerinha

    Porque este tipo de navegação nao funciona no IE?

  8. José Victor

    Esclarecedor este post. Mas estou precisando fazer com que o conteúdo das abas venha do servidor via AJAX quando a aba for clicada.
    Para isso acredito que o conteúdo das abas não poderia estar pré carregado nas divs separadas. Como eu poderia fazer isso?
    Grato.

  9. rogerio campos

    Testei o código e acho muito bom, mas quando tento colocar includes para paginas externas ao index, não consigo acertar um jeito de funcionar..

  10. Herbert

    ao clicar não mantém selecionado. Alguém chegou q ver isto?

  11. Herbert

    sobre o comentário anterior, já resolvi. Tava certo o script, eu q tinha feito o css errado

  12. rubens

    por favor sera que vc pudia me ajudar, eu usei seu exemplo so que coloquei um formulario e dividi ele nas abas so que quando, o mudo de abas os valor que estavam nos inputs do form somem.

    • Matheus

      Excelente essa solução em abas, gostei muito mesmo, mas também estou precisando descobrir como fazer para os dados dos inputs persistirem. Por favor, se tiver essa resposta nos ajude. Obrigado.

  13. Estou tentando colocar um slide dentro de uma das abas, porém ele está digamos que dando um conflito, acho que com o js, o que devo fazer para os 2 funcionarem juntos?

  14. helton

    Olá, quero parabenizá-lo pelo post, mas preciso de sua ajuda…. O plugin funcionou perfeitamente no IE e no Chrome, mas no Firefox a página abre totalmente desconfigurada… O que pode estar acontecendo?
    Obrigado.

  15. flavio

    Não consigo colocar nenhum include ele da um erro.

  16. Ana Paula

    No IE 9 não funciona, alguém teve esse problema!!! Muito bom seu site, parabéns! :-)

  17. Paulo RIcardo

    Parabéns! gostei muito do script. Só uma duvida, não estou conseguindo executar um formulário de contato dentro de uma dessas abas… Se puder me ajudar ficaria agradecido

  18. Otavio

    Como faço para funcionar com formulário dentro? Ele não submete o form…

  19. Jullio Reis

    Amigos, funcionou perfeito, mas gostaria de chamar diretamente uma determinada aba de um pagina externa e nao consegui fazer, ele abre sempre a primeira aba.

  20. Ricardo

    Gostei muito e estou tentando usar, mas o javascript não esta ativando as noticias. Alguem pode me ajudar?

  21. jansen

    Amigo parabens pela iniciativa, pesquisei isso pra caramba…

    Porem tenho uma dúvida a como colocar esse menu em uma pagina BLOGGER?

    Voce pode me ajudar, qualquer coisa posso pagar!

    Grande aqraço!

Participa! Comenta...