Canais iMasters

CSS + Web Standards

Layout CSS de 2 colunas com faux column

Neste artigo mostrarei uma técnica de construção de layout para uma página Web, sem uso de tabelas. O entendimento das propriedades de posicionamento é fundamental para a construção de layouts baseados em CSS . Conhecer com detalhes o comportamento de elementos posicionados com uso de:
position: relative; — position: absolute; — position: fixed; — float
é condição indispensável para começar suas primeiras tentativas de criar um layout.

Depois de conhecer como se comportam os elementos posicionados você terá que se aprofundar no estudo do comportamento diferenciado dos navegadores com relação a cada posicionamento.

A estrutura da página

Vamos construir um layout constituido por:

  1. um topo;
  2. uma coluna principal;
  3. uma coluna de navegação;
  4. um rodapé.

A marcação XHTML pura e a renderização podem ser vistas nesta página exemplo -1

O layout a construir

Nossa página terá as seguintes características:

  1. largura fixa de 760px;
  2. topo com 80px de altura na cor #df7ddf;
  3. coluna principal com 578px de largura na cor #99ccff;
  4. coluna de navegação com 180px de largura de altura na cor #ffbe7d;
  5. rodapé com 20px de altura na cor #b5daa2;
  6. coluna de navegação à esquerda e principal à direita

Notar que a soma da largura das colunas é igual a 578px + 180px = 758px. Como a largura total disponível é de 760px, teremos um espaçamento de 2px entre as colunas.

As primeiras regras CSS e a renderização podem ser vistas nesta página exemplo -2

Posicionando as colunas

Os elementos do layout estão com suas larguras e cores definidas, mas posicionados um embaixo do outro, formando uma pilha de DIVs (elementos nível de bloco), na ordem exata em que aparecem no código.

Vamos deixar o topo em cima, o rodapé embaixo e as colunas uma ao lado da outra. Para isto temos que posicionar as colunas. Usamos a declaração float: right; para a coluna principal e float:left; para a coluna de navegação. E complementarmente temos que "clarear" os elementos flutuados, para que empurrem o que estiver abaixo (no nosso caso o rodapé), declarando clear: both; para o rodapé.
Conforme já observado acima, esperamos um espaçamento de 2px entre as colunas, já que flutuamos uma para cada lado.

O efeito das novas regras CSS e a renderização podem ser vistas nesta página exemplo -3.

Adicionando conteúdo nas colunas

Vamos adicionar conteúdo nas colunas para ver como se comportam elementos floats com conteúdos.

Primeiro, conteúdo na coluna principal. Veja o que acontece nesta página exemplo -4.

Ops! a coluna principal cresceu para acomodar o conteúdo e "empurrou" o rodapé para baixo.
Mas, a coluna de navegação não acompanhou o crescimento (o que era de se esperar) e deixou um fundo diferente abaixo.

A seguir, conteúdo na coluna de navegação. Veja o que acontece nesta página exemplo -5.

Ops! A coluna de navegação cresceu para acomodar o conteúdo e "empurrou" o rodapé para baixo.
Mas, a coluna principal não acompanhou o crescimento (o que era de se esperar) e deixou um fundo diferente abaixo.

Conclusão: As colunas crescem independentes uma da outra, de acordo com o conteúdo nelas existente, e se tiverem cores de fundo diferentes o layout "quebrará" conforme mostrado nos dois exemplos.

A solução

A solução baseia-se em uma técnica CSS que foi denominada por Dan Cederholm de "Faux Columns" que podemos traduzir para "Falsas Colunas". Trata-se na verdade de simular a cor das colunas com uso de uma imagem de fundo.

Notar contudo, de que nada adiantará colocar a imagem como fundo da coluna individualmente. Temos que colocar a imagem no elemento que está por trás das duas colunas, para que quando acabe a coluna o fundo apereça por trás, dando a impressão de continuidade até o rodapé.

Vamos em frente.

O elemento que está por trás das colunas é a div#tudo. É nele que colocaremos uma imagem de fundo para simular a cor das colunas.

Uma imagem vale mais que mil palavras. Então, para entender o que vai acontecer, veja a seguir a imagem que colocarei como fundo e farei com que ela se repita na vertical, preenchendo todo o elemento.

Imagem para faux columns:

faux colums

A regra CSS para colocar a imagem de fundo na div#tudo e o resultado no nosso layout, pode ser visto nesta página exemplo -6.

Hum! agora sim, deu para ver que apesar de a coluna de navegação ter esticado para baixo, a cor da coluna principal estendeu-se até o rodapé. Compare com o a mesma página sem faux column.

E se o conteúdo esticar a coluna principal? Sem problemas e você já deve ter concluido o que acontecerá. Veja nesta página exemplo -7. Compare com o a mesma página sem faux column.

Notar por fim que aquele espaço de 2px entre as colunas foi preenchido com a cor preta existente na imagem da faux column, simulando uma borda. É claro que você pode deixar uma espaço maior ali e projetar uma borda decorativa entre as colunas.

Adicionando margens nos conteúdos

Você com certeza notou, quando viu a página exemplo -6, que os conteúdos das colunas tocam na borda esquerda. Para afastar o conteúdo alguns pixels do limite interno do seu container, usamos padding no container. Certo?

Sim, certo. Vamos colocar 8px de padding na coluna de navegação e 20px de padding na coluna principal, para as duas colunas, em ambos os lados do container.

A regra CSS para adicionar estes paddings e o efeito no nosso layout podem se vistos nesta página exemplo -8 onde eu retirei a faux column para melhor visualização.

Uau! isto ruiu meu layout. Sim ruiu, você viu né? Era esperada a ruína do layout. Vejamos:

Coluna principal: 578px + 20px + 20px = 618px.
Coluna navegação: 180px + 8px + 8px = 196px.
Soma das colunas: 618px + 196px = 814px

O container das colunas tem 760px e obviamente, não consegue conter 814px. A coluna principal não deixa espaço para acomodar a coluna de navegação à sua esquerda, e esta tem que flutuar logo abaixo dela como constatamos na página visitada.

Solução imediata: Diminuir 16px na largura da coluna de navegação e 40px na largura da coluna coluna principal.

Alternativa: Em lugar de padding para o container, definir margin para todos os elementos do conteúdo. Isto faz o mesmo efeito e não altera a largura das colunas. Usamos o seletor universal estrela (*) para casar todos os elementos do container.

A regra CSS e o resultado no nosso layout, pode ser visto nesta página exemplo -9.

Curiosidade: Se você visualizar a página exemplo -8 no IE 5.0 ou no IE 5.5 o layout estará perfeito, sem quebra. Você sabe responder porque isto acontece naqueles navegadores?

Bônus extra

Como bônus extra desta matéria, vamos centralizar nosso layout na página.

A regra CSS e o resultado no nosso layout, pode ser visto nesta página exemplo -10.

Descubra a versatilidade das CSS
Projete conforme as Web Standards.


Comente também

26 Comentários

Bruno Silva da Costa
Bruno Silva da Costa

Olá!!

Achei super interessante esse artigo, pois da uma clara ideia de desenvolvimento de layout utilizando CSS.

Agora, me responde uma coisa, qual e a resposta da curiosidade!!!

Leandro Severino
Leandro Severino

Mauricio,
Perfeito, prático, objetivo, com exemplos, modelos e muito bem comentado.
TODO, mas todo artigo publicado deveria ser assim.
Um abraço do colega Java-Cachaça.

J.S. Júnior
J.S. Júnior

CARA MUITO BOM MESMO O SEU ARTIGO ESTE É O PRIMEIRO ARTIGO QUE COMENTO POIS OS OUTROS NÃO MERECEM NEM O MEU COMENTARIO SENDO CRITICO OU NÃO O SEU TA PERFEITO PARABÉNS

Rodolpho Leal
Rodolpho Leal

Olá Mauricio! Estudo CSS há algum tempo, e sempre acompanho suas matérias, mas só agora me cadastrei pra poder postar comentários! Fico impressionado com a quantidade de recursos que o CSS nos trás, principalmente pra trabalhar com layouts baseados em imagens. Falando nisso, gostaria que você comentasse algum dia qual a maneira correta e mais leve de se trabalhar com esse tipo de layout.
Parabéns pela matéria!!! Abraços!

Giovani Magnaguagno
Giovani Magnaguagno

Muito fácil de entender este esquema. Mas Marcelo, me corrija se estiver errado, vc disse para "Em lugar de padding para o container, definir margin para todos os elementos", só que vc usou padding. E realmente o resultado é melhor.. e o mais importante é o uso do * no nome do estilo.

Felipe Sander
Felipe Sander

sobre esta parte: "Alternativa: Em lugar de padding para o container, definir margin para todos os elementos do conteúdo. Isto faz o mesmo efeito e não altera a largura das colunas. Usamos o seletor universal estrela (*) para casar todos os elementos do container."

Você usou padding e não margin, não entendi.

Pq o padding (que é o espaço DENTRO da div até a borda) altera a largura de uma div???

Nunca entendi pq o padding faz isso, poderia explicar melhor?

Grato.

luiz carlos oliveira e silva
luiz carlos oliveira e silva

CARA DIMAIS, vlw mesmo quando eu olho uma coisa dessa assim eu quase tenho um orgasmo :p css e phoda, eu acho que no ie5 o layout fica normal pq ele nao compreende direito css, eu acho, nao tenho certeza. E isso mesmo?

Mauricio Samy
Mauricio Samy

Onde se lê:
Alternativa: Em lugar de padding para o container, definir margin para todos os elementos do conteúdo.

Leia-se:
Alternativa: Em lugar de padding para o container, definir padding para todos os elementos do conteúdo.

Danielle Maranhão
Danielle Maranhão

Realmente, excelente artigo...tabela nunca mais! Gostaria de continuar aprendendo através da sua didática. Parabéns!

Nixon Elias Santos Alves
Nixon Elias Santos Alves

Olá Mauricio tudo bem? Muito boa a didática deste artigo seu. Parabéns. Eu trabalho com CSS a um bom tempo mais nunca precisei usar nos meus layouts os famosos
position: relative e absolute

A maioria dos layouts que eu faço é sem o uso da tabela mais não uso o position e ele não quebra o layout nos browsers firefox, IE, Ópera, nestacape. sabe explicar o por que disso? Sempre os layouts ficam ótimos em qualquer resolução. talvez seja por que eu limito o tamanho das divs. Mais uma vezes parabéns pelo artigo.

Ruy Burgos dos Santyos
Ruy Burgos dos Santyos

Maurício comecei a aprender css com suas matérias e me surpreendi com o que podemos fazer com este recurso. Gostaria de dizer que a matéria é ótima e coincidentemente (ou não) acabo de me deparar com o problema deste artigo. Porém não posso de deixar de observar uma limitação do que foi feito, pois se ambas as divs possuirem um tamanho não fixo (com width e height) a imagem apareceria deslocada quando a página fosse vista em diferentes resoluções. Corro atrás de uma solução. Grande abraço. Valeu Imasters!

Mauricio Samy
Mauricio Samy

Esta materia, como foi dito , comtempla layout FIXO.
A técnica para layout fluido é outra.

Pablo Pereira
Pablo Pereira

A tempos que leio artigos deste tipo sobre css, mas com uma didática dessas nunca tinha visto. Parabéns Maurício! Por favor continue escrevendo artigos desta forma que se torna muito fácil de entender. também é o primeiro comentário que faço ... esse mereceu.
Valew

fabiana rangel
fabiana rangel

foi de grande utilidade e muita didática seu tutorial, realmente pra mim como leiga foi de grande valor!
Obrigada

Nelson Vasconcelos
Nelson Vasconcelos

Maujor, essa sintaxe de ensino foi muito boa, e esse é um dos seus melhores artigos!

Vinicius Mendes
Vinicius Mendes

Gostei muito do artigo, já tinha visto algo parecido no seu site.

Mas uma duvida que eu tenho é como fazer pra ter objetos float dentro de divs com float...

sempre me confundo com isso :S por isso que em alguns casos prefiro usar os positions.

Luis Henrique
Luis Henrique

ficou excelente sua materia. parabens!

Edegar Belz
Edegar Belz

Maurício, gosto muito das suas matérias e, aliás, boa parte do que sei sobre CSS aprendi no seu site.
Mas dessa vez preciso fazer uma crítica.
Desculpe-me pela expressão mas, convenhamos, faux column não passa de gambiarra, se levarmos em consideração a finalidade do CSS/Tableless.
Senão vejamos:
E se eu quiser mudar em 10px o tamanho de cada coluna? Ou se simplesmente quiser inverter a ordem das colunas apenas alterando o CSS? (aliás isso foi tema de outro artigo seu)
Ou, como outro usuário falou, eu quiser que as colunas adquem-se ao meu conteúdo?
Em qualquer dos casos citados a técnica de faux column vai por água abaixo.
Eu teria que abrir meu editor de imagem e alterar a imagem pra cada nova possibilidade que eu quiser testar.
Imaginei que talvez colocando "height: 100%" nas duas colunas poderia resolver, mas testei e parece que esse par propriedade/valor não existe.

Portanto, convenhamos mais uma vez, neste ponto a alternativa é: TABELA.
;)

Abraço e parabéns por todos os seus outros artigos, que são de altíssimo nível.

Maurício Gonçalves Marques
Maurício Gonçalves Marques

Maurício, além de ser meu chará, vc é fera em suas publicações. A muito tempo acompanho suas matérias e elas me influenciaram diretamente para que eu pudesse a crescer mais como profissional!
Somente um pedido:
Como criar uma página para "versão de impressão"!?
Pode me mandar um email!
maux.webmaster@gmail.com
Abraços!

Rafael Antunes
Rafael Antunes

Ótimo artigo, estou fazendo um site em css nesse molde, ainda entrei no seu site e to mandando ver no css. Parabéns!!!

Renan Oliveira da Costa
Renan Oliveira da Costa

realmente eesa matéria foimuito boa!!! Esse "jeitinho" de utilizar uma imagemna div principal resolveu meu problema!!!! Valeu Maurício!! Ah, tô aprendendo muito no seu site...

Marcus Crisostomo
Marcus Crisostomo

Ótima matéria, pois atravéz dela eu pude ver de uma forma mais clara como eu posso montar os meus lay-outs via CSS me livrando de uma vez por todas de tabelas! Valeu!

Andrea Guimaraes
Andrea Guimaraes

Gostei muito da matéria. Você centralizou todo o layout horizontalmente, porém se eu quisesse centralizar na vertical, como eu faria? Já tentei de várias maneiras e não consegui.

Raphael França Marques
Raphael França Marques

p/ andrea: Bom, eu não sei se está certo mas para alinhar vertical e horizontalmente eu coloco TODO o conteúdo do site em uma tabela de width e height 100% e com apenas uma linha/coluna. Dentro da propriedade do td eu coloco align=center e valign=middle ai fica certinho. Ficaria assim: <table width="100%" height="100%"><tr><td valign="middle" align="center"> codigo da pagina aqui </td></tr></table> .. não sei se está correto mas funciona hahahahah.. Sobre a matéria, desculpe a palavra mas CARALHO!!!!! muito boa, nunca pense i que acharia um artigo tão bem explicado, com tantos exemplos !!!!!! tiro meu chapéu! Melhor, meu boné, pq não uso chapéu hahah! Espero ver mais artigos bons iguais a este! By the way, vou ler todos os outros artigos teus, nunca tinha passado aqui no css pq sempre achei que era ultra difícil >_< hahahah abração

Ricardo  Rocha Pereira
Ricardo Rocha Pereira

Tenho uma DIV Container e quero que ela aumente de acordo com o conteúdo, portanto, eu setei o height como auto.

Dentro dessa DIV tenho duas DIVS que gostaria de colocar uma do lado da outra, porém, se eu uso float ou position nelas, a minha DIV container simplesmente para de acompanhar o conteúdo e o tamanho das DIVS que gostaria de colocar uma do lado da outra.

Como eu posso colocar uma div do lado da outra sem usar FLOAT (left ou right) ou POSITION (absolute ou relative)?

Existe uma outra solução?

Flávio Souza
Flávio Souza

interessante, é ah primeira vez que tenho contato com o assunto css, gostei mesmo

Qual a sua opinião?

Comentários considerados ofensivos serão moderados.

Parceiros

IBM
PagSeguro
Internet Innovation
Dialhost
HostNet
Tecla
KingHost
DotStore
Dinamize