Centralizando floats com largura variável e um bug no IE 7

Trabalhar com elementos com float nas páginas é uma tarefa bastante comum. A idéia do float, como podemos deduzir dos seus valores possíveis, é posicionar objetos à esquerda ou à direita. Porém, nem sempre temos esta intenção ao usar floats.

Um caso bastante típico é quando usamos float apenas para poder colocar altura, largura ou margens verticais num elemento. Como o float força um display: block, podemos aplicar height, width e padding (vertical) neste elemento.

Num segundo cenário, já encontrei casos em que tenho um elemento de largura variável e não previsível e, que tenho também de deixá-lo centralizado na página ou em relação a um outro elemento pai. Este é um dos casos onde precisamos centralizar floats.

Eu já conhecia esta técnica aqui do Stu Nicholls em seu site CSSplay. Já usei este método e sei que ele funciona bem. Tudo bem que ele usa uma tag del (pode ser uma ins também) sem necessidade... mas, com comentários condicionais podemos esconder ela dos navegadores atualizados e deixá-la visível apenas para o Internet Explorer (sim, como já era de se imaginar, a tag é necessária apenas para o IE).

Lendo o doggdot.us hoje, achei uma referência para outro artigo que descreve uma segunda técnica, mais simples e objetiva. Testei o exemplo disponível e funcionou no Firefox, IE 7 e 6. Apenas no IE 7 é que surgiu a barra de rolagem horizontal. Nada muito complicado de se resolver.

O IE 7 tem um bug (certo, muitos bugs, mas vamos falar só desse) que um elemento pai com overflow: hidden e um filho com position: relative, faz com que o efeito do overflow não funcione. Se você adicionar position: relative no pai também, terá o resultado esperado. Acabei de deixar um comentário ao autor sobre esta correção. :D Veja mais sobre este bug.

Ficam aí as dicas para quando você precisa centralizar elementos com float ou se deparar com este bug do IE 7, bom proveito! =)

Referências
Centralizando floats - Método simples
Centralizando floats - Método do Stu Nicholls
Comentários condicionais (conditional comments)
Bug do IE 7 com overflow e position

comentários (2)

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! =)

Referências
CSS
A propriedade float
Técnica easy clearing
O hasLayout do IE
Ativando o hasLayout

comentários