2007 09/01
Float, zoom, hasLayout e clearing floats
Se você trabalha com layouts web e usa CSS, já deve ter usado muito a propriedade float.
Sendo assim, todas as palavras que usei no título deste post já são velhas conhecidas nossas. =) Caso você ainda não as conheça e/ou já tenha enfrentado alguns problemas ao usar float, vou discutir aqui algumas soluções que você pode usar quando se deparar com algum problema relacionado.
Afinal, qual o problema?
Para ilustrar o que acontece, nada melhor que um exemplo simples. Considere o seguinte markup:
<ul id="menu">
<li>Menu A</li>
<li>Menu B</li>
</ul>
Um markup simples, que podemos usar em muitos casos para representar um menu de opções.
Agora imagine que você gostaria (ou seu layout quer assim =) que as opções do menu estivessem uma ao lado da outra, com uma altura fixa qualquer para as opções. Em outras palavras: abas.
Tudo muito simples! Basta aplicar um float: left ou right em cada item do menu e problema resolvido.
Aplicando float nos itens do menu vai também aplicar display: block no elemento. Sendo assim, você também vai poder aplicar a altura em cada item. Transformando tudo isso em regras CSS:
#menu li {
background: #c30;
float: left;
line-height: 50px;
}
Adicionei uma cor de fundo para facilitar a visualização (se você fizer o teste, claro).
Agora, para nossas abas terem um destaque maior, vamos colocar elas sobre uma cor de fundo especial. Vamos usar o próprio ul que temos ali para isso. O nosso CSS agora fica (a parte nova está em negrito):
#menu {
background: #039;
}
#menu li {
background: #c30;
float: left;
line-height: 50px;
}
Testando nossa página vemos que a cor (#039) que definimos para nosso ul não apareceu, tanto no Firefox como no Internet Explorer 6. E agora?
Resolvendo o problema no Firefox
Para resolver o nosso problema no Firefox é simples. Basta empregar uma técnica conhecida por, dentre vários nomes, easy clearing.
Adicionando a técnica ao nosso CSS original, temos:
#menu {
background: #039;
}
#menu li {
background: #c30;
float: left;
line-height: 50px;
}
#menu:after {
clear: both;
content: ".";
display: block;
height: 0px;
visibility: hidden;
}
O funcionamento da técnica é simples. Ela vai criar algum conteúdo dentro do elemento (com a propriedade content) e vai fazer com que ele fique depois de todo o conteúdo (com o pseudo-elemento :after)
Como este novo conteúdo não tem float, ele vai ficar abaixo de todo mundo, forçando o aparecimento do nosso ul tímido. =)
Pronto, o problema no Firefox está resolvido. Agora só falta resolver no nosso amigo IE.
Para os mais atentos, no endereço que passei da técnica acima, a solução para o IE já foi abordada. Porém, vou usar uma forma ligeiramente diferente e, na minha opinião, mais prática para resolver o problema.
Resolvendo o problema no Internet Explorer
A solução para o IE é ainda mais simples, embora proprietária. Consiste basicamente em ativar a propriedade hasLayout do elemento que não está aparecendo, no nosso caso: ul.
Veja a explicação técnica para o funcionamento deste método.
Várias propriedades ativam o hasLayout, como dito no link acima. As mais usadas são definir a altura (height) ou o comprimento (width).
O fato é que há, não raros, casos em que se você aplicar umas das propriedades elas irão afetar visualmente sua estilização atual. Atualmente eu passei a usar a propriedade (proprietária) zoom, que vai funcionar somente no IE e sem alterar nada visualmente.
Adicionando a nossa nova propriedade ao que já havíamos conseguido, temos:
#menu {
background: #039;
zoom: 1;
}
#menu li {
background: #c30;
float: left;
line-height: 50px;
}
#menu:after {
clear: both;
content: ".";
display: block;
height: 0px;
visibility: hidden;
}
Pronto, o mesmo resultado também no IE. =)
Resumindo
Usar as técnicas de easy clearing em combinação com a ativação do hasLayout no IE, vai resolver boa parte dos seus problemas quando um elemento não quer aparecer na página sendo que seus filhos, todos, estão com float.
Só um detalhe: no momento eu não me recordo aonde exatamente eu li um comentário ou post recomendando o uso da propriedade zoom ante height/width. Se você sabe de quem partiu a idéia original, por favor, deixe seu comentário! =)