Resolvendo o problema dos layouts de três colunas com elementos clear: both na coluna central
Faz muito tempo que eu não escrevo sobre CSS ou mesmo tutoriais de caráter geral no blog.
Parte da culpa disso é o tempo, mas também tem o fato que hoje, layouts utilizando CSS são a norma, e não há tanta necessidade de divulgar os Padrões Web. Além disso, existe material extenso espalhado pela rede, e não quero ficar replicando este conteúdo.
Contudo, esta semana eu parei para estudar um tema do meu gerenciador de conteúdo preferido (sim, é o Drupal), pois descobri que um problema que acontece eventualmente em meus layouts CSS, não ocorre no tema.
Existe várias maneiras de se resolver o mesmo problema usando CSS, e provavelmente o meu problema não afeta todos os desenvolvedores de internet. Contudo, a minha forma de criação de layouts de 3 colunas é uma das mais comuns, então esse problema eventual (que na verdade não é um problema, é o comportamento esperado, mas é um pé no saco) deve afetar várias pessoas
Que problema seria este? É que quando você cria um layout de três colunas (duas menores laterais e 1 central, mais larga), você pode colocar elementos com a propriedade clear:both na coluna central, ou seu layout irá quebrar.
Descrição do problema passo-a-passo
- Você cria um layout simples em CSS, de três colunas, que tem a seguinte estrutura:
<div id="auxiliar1">
</div> <!-- /#auxiliar1 -->
<div id="auxiliar2">
</div> <!-- /#auxiliar2 -->
<div id="conteudo" class="cont">
conteudo da pagina<hr />
</div> <!-- /#conteudo -->
e utilizando o seguinte CSS para formatar:
#auxiliar1 {
float: left;
width: 190px;
}auxiliar2 {
float: right; width: 190px;}
conteudo {
margin: 0 204px;}
O resultado até agora pode ser visto aqui.
-
Você adiciona uma caixa, feita com uma div de dimensões fixas e com float: left. Só que como é uma div flutuante, a caixa excede as dimensões do seu container. Veja um exemplo aqui.
-
Eu não quero que isso aconteça. Quando você não quer que um elemento flutuante invada ou ultrapasse um elemento, você pode usar a propriedade clear. clear: left impede elementos flutuantes à esquerda do elemento formatado, clear: right à direita, e both de ambos os lados. Eu posso aplicar clear: both (ou left, ou right) a por exemplo, àquela linha "hr" que sucede a caixa. Só que isso faz com que o hr seja exibido apenas depois das colunas laterais (que são posicionadas com float), gerando um buraco enorme na página. Veja um exemplo.
Uma solução alternativa seria definir uma altura mínima à div que engloba a caixa, mas esta solução não é muito boa, especialmente se você está lidando com elementos de tamanho variável.
A solução Passo-a-Passo
A solução é bem simples. Em vez de simplesmente tentar contornar o problema, vamos mudar a forma como a página é construída. O resultado vai ser o mesmo.
- Pegue a mesma estrutura da página utilizado nos exemplos 1, 2 e 3, e adicione mais uma div, englobando a coluna central. Eu chamei esta div de "center".
- Posicione as colunas laterais naturalmente, ou seja, utilizando float. Mas aplique position: relative e z-index: 2 em ambas as colunas laterais, para contornar um problema com o Internet Explorer 6 e 7 (os links nas colunas laterais ficariam inclicáveis sem isso).
- Aplique uma margem negativa esquerda e direita à div center equivalente às larguras totais das divs laterais. Aplique também à esta div a propriedade float: left e width: 100%.
- Na div da coluna central (que eu chamei de conteudo), adicione uma margem esquerda e direita equivalente às larguras totais das divs laterais.
Basicamente só seria necessário este procedimento para que o layout funcione certinho, mas infelizmente devido à interpretação equivocada do modelo de caixa do IE6, talvez seja necessário adicionar um CSS Hack, que pode ser feito colocando um "_" no início da propriedade, ou o mais recomendado, utilizar um arquivo à parte e usar comentários condicionais para inserí-lo na página. Antes que eu esqueça, vejam o resultado no exemplo 4.
Obviamente, ambas as formas de criar o layout estão corretas, e possuem as suas vantagens e desvantagens. A que eu utilizava anteriormente é muito mais simples de ser feita, mas apresenta seus problemas com elementos com clear. A segunda é mais complexa, requer mais divs e mais linhas de CSS, mas não tem problema com clear. Fica como mais uma opção para desenvolver o layout.
A sim, antes que eu esqueça, a solução apresentada aqui funcionou em todos os navegadores (testado usando o site Browsershots), e também funciona com layout fluido e com layout de apenas duas colunas.