Alinhamento Vertical de Divs com JavaScript e JQuery

Passei um sufoco esses dias tentando alinhar um div dentro do outro apenas com CSS, o qual aliás não consegui nada satisfatório, mesmo achando algumas técnicas interessantes que não chegaram a funcionar comigo. Então parti para o JavaScript, para me ajudar. :)

Como neste projeto que eu precisava alinhar os divs, eu já estava usando a biblioteca JQuery (que por sinal tem um slogan legal - "Write less, do more" ou seja, escreva menos e faça mais), fiz o alinhamento usando ela mesmo.

Aqui está a explicação do problema:

Alinhamento Vertical

Onde eu tenho uma div maior, com altura definida. Um div (que tive que adicionar para poder alinhar) com altura variada por conter o texto e uma imagem os quais não tenho controle das suas respectivas alturas.

O primeiro detalhe que temos que fazer é adaptar o código (x)html para ser alinhado. Como disse tive que adicionar um div (o da altura variada), pois sem ele nada feito.

HTML:
  1. <div class="alinhar">
  2. <div><img src="http://www.tuliofaria.net/imagem.jpg" />
  3. texto</div>
  4. </div>

Obs.: não pode haver nenhum espaço ou texto entre os dois divs, porque senão haverá um textNode entre eles e a técnica não funcionará. Tenho que arrumar um workaround para isso e para a preguiça. :)

[UPDATED 10/07/2007]

Agora vem a parte divertida, JavaScript, para conferir o código entre aqui e veja o Código Fonte de Exemplo.

Obs.: me desculpem por não ter percebido esse erro. Realmente o editor do blog cortou uma parte do fonte JS.

[/UPDATED 10/07/2007]

O que esse código faz, resumidamente, é pegar a altura dos dois divs, subtrair e dividir esse resultado por dois. Para saber o valor do padding-top que temos que definir no div de altura fixa. Que é o mesmo valor que tiraremos de sua altura.

Por que usei setTimeOut? Porque estava dando alguns problemas de não reconhecer a altura dos divs logo após o carregamento da página, assim depois de 1000ms possivelmente já terá renderizado corretamente.

Para baixarem a JQuery: www.jquery.com

Bom pessoal, até a próxima. Qualquer dúvida, comentem :)

30 Comentários »

  1. Gustavo Gonçalves said,

    Janeiro 27, 2007 @ 11:14

    Fala Túlio. Gostaria que falasse mais sobre JQuery, escrevendo meio que um "tutorial de introdução". Utilizo hoje o toolkit DOJO, porque me permite criar classes e heranças e importar outras bilbiotecas de uma maneira semelhante a que que programo em JAVA. Entretanto, estou tendo problemas com o tempo de carga, o browser "engasga" e não responde até todos os arquivos estarem carregados. Em fim, gosto muito do DOJO mas isso está me criando problemas.

    Estou em dúvida pra que lado vou correr, estou tendencioso para Mochikit. Como JQuery se compara a Dojo, Mochikit e Prototype? Pq escolheu este toolkit?

  2. tulio said,

    Janeiro 27, 2007 @ 12:43

    Blz Gustavo,

    comecei a trabalhar com o JQuery como uma alternativa ao Prototype. Alguns dos fatores que me motivaram a começar a usá-la foram o seu tamanho (menor que o prototype) e o esquema de expressões que ela possui, assim conseguimos buscar um elemento na página usando atributos (e outros parâmetros), não apenas baseado no seu nome, id ou classe. E também por ela possuir "Efeitos", como os do scriptaculus nativamente. Além de várias outras vantagens.

    Em um projeto grande que estou desenvolvendo atualmente, como não tenho muito problema com o tamanho do site (pelos usuários que irão fazer uso do sistema), estou usando tanto a Prototype quanto a JQuery, pois já haviam implementações usando o Prototype.

    Pretendo escrever algo sobre ela sim, e atualmente recomendo o uso, pois ela justifica o lema: "Write less, do more" (escreva menos, faça mais).

    Espero ter te ajudado na escolha :)

    Abraços,

  3. Allan said,

    Janeiro 28, 2007 @ 23:51

    Eu to usando o Jquery em um projeto e está sendo muito util , principalmente o plugin de AjaxForm, depois da uma olhada. Vale a pena!

  4. Gustavo Gonçalves said,

    Janeiro 29, 2007 @ 10:30

    Realmente 19Kb para o JQuery é muito interessante!

    Dojo é bastante poderoso quanto a buscar elementos por classes e atributos, mas no que diz respeito a velocidade, perde muito.

    Dojo tem um problema de "congelar" o navegador, que é quase uma marca registrada da biblioteca. Isso me irrita muito. O pior, só fui perceber isso depois de programar várias linhas e colocar minha aplicação para rodar na Web.

    Nos testes locais este problema não aparecia! Depois fui buscar informação sobre porque isso acontece, parece que é uma necessidade de sincronia entre o HTML/CSS/JS antes que tudo comece a rodar. Uma bosta. Tem maneiras de diminuir este "congelamento", mas ele vai sempre existir.

    O problema que tenho agora é que o Dojo me permitiu modelar o sistema como classes, utilizando herança, construtores, etc. A biblioteca que preciso escolher deve me permetir trabalhar desta maneira também, ou vou ter trabalho dobrado em adaptar o código.

    JQuery parece uma forte promessa, tudo muito bem documentado, fácil de aprender. Só preciso ver se posso dar esta abordagem de classes. E ainda estou vendo o MochiKit pq tenta espelhar Python para JS e eu curto muito Python.

    Veremos, comunico aqui ao site qdo tomar uma decissão.

    Abraços

  5. Rafael Santos Sá said,

    Março 25, 2007 @ 01:18

    O post já tá aí desde janeiro, mas só agora encontrei teu blog, pois buscava informações sobre o Cake.
    Maneiro o pessoal estar se interessando por jQuery, já sou discípulo desde o release 0.2 do jQuery e desde meados de 2006 venho tentando evangelizar a linguagem por aqui hehe.
    Só que como meu blog nunca sai do 0. Sorte tem tu está ai fazendo este ótimo trabalho de video aulas (pelo menos no Cake) e eu tinha pensado em fazer isso para jQuery e agora vou fazer mesmo.

  6. Rafael Santos Sá said,

    Março 25, 2007 @ 01:20

    Ah, no seu post, pode ser transformado em 'alinhando divs com jQuery' somente, indico a todos a buscarem o plugin dimension que te permite pegar a posição/tamanho de qq elemento na tela. De uma forma ridiculamente simples. Jquery-style.

  7. Bruno said,

    Abril 6, 2007 @ 09:30

    Perdão, mas tem algum erro com os laços for() da sua função?

    Se "copiar e colar" e usar no $( document ).ready( function() da jQuery, o Firebug do Firefox acusa erro.

    Preciso demasiadamente dessa "correção", mas com os erros de nada adianta. Acredito que seja pelo fato de a função estar quebrada em várias linhas, não sei.

    Poderia ajudar?

    Obrigado

  8. Comunidade jquery Brasil » Blog Archive » Alinhamento Vertical de Divs com JavaScript e JQuery said,

    Abril 6, 2007 @ 11:10

    [...] ARTIGO PUBLICADO POR Túlio Faria ORIGINALMENTE EM: http://www.tuliofaria.net/alinhamento-vertical-de-divs-com-javascript-e-jquery/ [...]

  9. Bruno said,

    Abril 9, 2007 @ 11:39

    Amigo(a) jQuery Brasil, se sua intenção foi ajudar minha dúvida, aredite, não ajudou não, pois o link que você passou remete a esta mesma página.

    Grato

  10. Tulio Faria said,

    Abril 9, 2007 @ 13:52

    Olá amigo,

    acho que você não entendeu... Esse comentário quer dizer que este post foi linkado ao site jQuery Brasil...

    sobre a sua pergunta, eu não entendi direito onde está o problema, já que este script foi testado...

    passe mais detalhes para que eu possa lhe ajudar...
    t+

  11. Danilo Freitas said,

    Abril 9, 2007 @ 16:54

    Também tive o mesmo problema, veja o debug do firefox:

    Erro: missing ; after for-loop condition
    Arquivo-fonte: file:///C:/Documents%20and%20Settings/danilo/Desktop/align.html
    Linha: 28, Coluna: 6
    Código-fonte:
    divs = $(ids[x]);

    segue o codigo do arquivo

    texto

    var vTime;
    function centraliza(){
    var ids = new Array();
    ids.push("div.alinhar");
    for(x=0;x
    divs = $(ids[x]);
    for(i=0; i
    h = divs[i].offsetHeight;
    hp = divs[i].childNodes[0].offsetHeight;
    padd = parseInt((h-hp)/2);
    nh = h-padd;
    $(divs[i]).css( { height: nh+"px" } );
    $(divs[i]).css( { paddingTop: padd+"px" });
    }
    }
    }
    $(document).ready(function(){
    vTime = setTimeout("centraliza()", 1000);
    });

  12. Danilo Freitas said,

    Abril 9, 2007 @ 16:55

    bem filtrou as tags... :(

  13. Danilo Freitas said,

    Abril 9, 2007 @ 17:02

    Amigo, olhei direito, há alguns erro no seu post, tente copiar e colar do seu site, n funciona. OK?

  14. Bruno said,

    Abril 9, 2007 @ 18:51

    Pode ser por causa dessa filtragem de tags que o sript não funcionou.

    Teria como você passar o script em um arquivo de texto puro ou sem passar pelo editor do blog?

    Obrigado

  15. Tulio Faria said,

    Abril 10, 2007 @ 00:31

    Bruno e Danilo Freitas,

    realmente estava errado no post. Sinceras desculpas. E obrigado pelo alerta.

    Agora está corrigido.

    Até mais,

  16. Bruno said,

    Abril 10, 2007 @ 09:48

    Bom, não atualizei no servidor para adicionar o código. Mas ocalmente a mesma estrutura do servidor não consegui fazer funcionar.

    http://www.imaggens.net/admin.php?act=settings&section=system

    Esse é o link. O código é o mesmo.

    Porém não sei como fazer para adicionar corretamente em ids.push() as DIV's

    Pode me ajudar?

  17. Tulio Faria said,

    Abril 10, 2007 @ 13:06

    Olá Bruno,

    então você usaria um ids.push para cada div ou elemento em bloco que deseje centralizar.

    No caso do exemplo está ids.push("div.alinhar"), ou seja, ele vai pegar todas as divs com classe alinhar e aplicar a centralização.

    Este "div.alinhar" segue o padrão de expressões do jQuery, ou seja, pode-se usar qualquer expressão válida (em jQuery).

    Você pode conferir mais sobre isso em: http://docs.jquery.com/Selectors

    Até mais....

  18. Bruno said,

    Abril 22, 2007 @ 12:11

    Deu não Túlio.

    Eu remontei o layout com ajuda de um amigo e agora ficou até que mais simples, embora tenha uns probleminhas de fluidez entre resoluções. Mas não vem ao caso.

    E aparentemente, o seletor que deveria usar é li.right, mas não acontece nada.

    O link do site é o mesmo ainda

    []'s

  19. Tulio Faria said,

    Abril 24, 2007 @ 10:03

    Olá Bruno,

    então é porque você não tem um li tipo:

    HTML:
    1. <li class="right">Centraliza</li>

    Att,

  20. Bruno said,

    Abril 26, 2007 @ 12:43

    Ops, falh nosaa. A página que tem o li.riht é qualquer uma de dentro de uma das castegorias do link que eu passei, onde ficam as configurações detalhadas.

    []'s

  21. FERDINANDO said,

    Abril 30, 2007 @ 18:19

    Em algum lugar dos comentarios acima, vc comenta, que o browser se enrola para baixar o codigo .JS, isso nao acontece com o JQUERY, o que ele faz pra ser mais rapido, vc manda por exemplo, um formulario INDEX.HTML, com 5 scripts relacionados, eu sei que enquanto nao carregar todas as .JS, o INDEX.HTML, nao vai aparecer, isso fica mais rapido com o JQUERY?
    []s ... Sucesso

  22. Tulio Faria said,

    Maio 3, 2007 @ 18:31

    Olá Ferdinando,

    não entendi muito a sua questão...

    Inté +

  23. arbomxseqh said,

    Junho 18, 2007 @ 22:53

    Hello! Good Site! Thanks you! zaibzkrjxye

  24. João Gabriel Maluf said,

    Fevereiro 3, 2008 @ 18:58

    É realmente é interessante, mas não concordo com a idéia de utilizar-se do Jquery, muito menos o prototype, eles são pessados, lentos e cheios de bugs, além de limitarem completamente o programador, concordo com a pratica sadia de ver o que eles fazem e fazer melhor no seu código, não só de usá-los sem saber o que esta fazendo.
    Claro que visto o ganho de tempo pode ser considerado uma vantagem, porém vejo como coisa de quem tem preguiça de pensar pra fazer algo tão simples.

    Veja o código:

    if(window.addEventListener)
    {
    window.addEventListener("load", function() { centraliza(); }, false);
    } else
    if(window.attachEvent)
    {
    window.attachEvent("onload", function() { centraliza(); });
    }
    function centraliza(){
    tam=document.documentElement.clientHeight;
    divisao=document.getElementById('teste').style.height;
    tamstr=(divisao.length)-2;
    divisao=divisao.substr(0,tamstr);
    margem=(tam-divisao)/2;
    document.getElementById('teste').style.marginTop=margem+"px";
    setTimeout("centraliza()", 10);
    }

  25. João Gabriel Maluf said,

    Fevereiro 3, 2008 @ 19:00

    O HTML

  26. João Gabriel Maluf said,

    Fevereiro 3, 2008 @ 19:01

    <div id="teste" style="width:910px; height:400px; margin:auto; background:#000066;">
    </div>

  27. Tulio Faria said,

    Fevereiro 3, 2008 @ 20:07

    João,

    é claro que se fosse para usar somente para o alinhamento poderia ser muito código (eu não acho muito não).

    Imagine em um script maior que você usasse:

    document.getElementById

    muitas vezes, você estaria escrevendo muito código a toa. Não concorda?

    Sem contar na perda de produtividade, re-uso de código e por aí vai....

    Bom essa é minha opinião....

    Abraços,

  28. Joaz Soares said,

    Março 3, 2008 @ 15:30

    Funcionou perfeitamente no IE 7 e 6 soh naum deu certo no FIREFOX... alguma sugestao??

  29. CInaglia said,

    Março 9, 2008 @ 03:15

    Joaz, eu tive esse problema no FIREFOX também,
    Depois descobri que a imagem não pode ter espaço entre o . Por ex,

    é necessario estar assim:

    Caso contrário teremos um problema no Firefox,
    Grande abraço.

  30. Joaz Soares said,

    Março 10, 2008 @ 08:26

    Perfeito! Acho que eu nunca iria desconfiar disso!

    muito obrigado =)

RSS feed for comments on this post · URI do TrackBack

Deixe seu comentário