CSS - float ou overflow?

Hoje, em CSS, temos basicamente duas formas de conter flutuação em CSS: com o próprio float, ou usando overflow. Qual a melhor forma? Qual a forma correta? Quando eu devo usar? Nesse artigo, veremos as vantagens e desvantagens dos dois modos! Vem comigo :D
Simulando o problema
É mais fácil visualizar o problema, já que estamos falando de CSS. Então, vamos escrever um pouco de código que eu vou explicando o que acontece :)
Crie um arquivo index.html, com o seguinte código:
1 |
|
Um simples HTML, com uma div, que contém um parágrafo e uma imagem. Agora vamos estilizar para deixar tudo um pouco mais bonito. Pode usar o CSS abaixo no HTML mesmo, somente para exemplo. Coloque o código abaixo da tag <title>:
1 | <style> |
E temos o seguinte resultado:

Olha que lindo! Nossa div com um fundo bastante exótico, a imagem, e o texto logo abaixo. Agora nós queremos posicionar nossa imagem do lado direito do texto. O que precisamos fazer? Isso mesmo, flutuá-la!
Vamos então adicionar o estilo para flutuar a imagem. Coloque o código abaixo, logo após o CSS da div:
1 | img { |
E olha o que aconteceu:

A imagem ficou pra fora do nosso box! Mas não é isso que queremos! Ela faz parte do box, e deve ficar dentro dele, respeitando o padding de 15px que eu coloquei no box. Temos duas formas de “resolver” isso.
Overflow para conter a flutuação
Podemos usar overflow no container pai para conter a flutuação:
1 | div { |
Na linha 3, adicionamos um overflow: hidden, e agora, olhe o que aconteceu:

Perfeito! Era exatamente o que queríamos! Já acabou?
Calma criança! Ficou exatamente como esperávamos, NESSE CASO. Agora imagine que o designer que fez o layout é todo descolado, e fez um badge que vai ficar posicionado no canto superior esquerdo, um pouco para fora do box.
Vamos adicionar o badge no nosso código:
1 | <div> |
E vamos posicioná-lo no canto superior esquerdo do box:
1 | div { |
Deixamos a div com posicionamento relative (linha 5), para que o badge não se perca, e fique posicionado absolutamente, mas sempre relativo à div.
Olha o resultado que coisa mais fofa:

Nosso badge ficou lá no canto, mas só apareceu 1/4 dele! Cadê o resto?
O overflow conteve a flutuação, mas, em conpensação, impede que qualquer filho do container ao qual foi aplicado o overflow, apareça fora da área delimitada =/
Resultado:
Usar overflow resolve o problema de conter flutuação? Sim, em partes. A menos que você precise que, algo dentro do box, fique um pouco para fora.
É a solução correta? Não.
Usando float para conter a flutuação
Agora vamos ver como fazer o mesmo, mas usando float. Vamos remover o overflow da div e colocar um float: left:
1 | div { |
E o resultado:

Ótimo, coisa linda! Mas perae, tem um problema… Nosso box não ocupou toda a largura da tela. Como ele está flutuado e não tem width definido, a largura dele será baseada no tamanho dos itens internos.
Ah, mas isso é fácil de resolver: só colocar um width: 100% na div!
Vamos fazer isso então:
1 | div { |
Como ficou?

Olhe o que aconteceu: ficou “quase” da forma como queríamos. O problema foi que, como nosso box tem um padding de 15px em cada lado (30px na vertical, e 30px na horizontal), os 100% da largura foram somados aos 30px horizontais! Ficamos com um box que tem 100% + 30px de largura!
Tem como resolver isso de outra forma?
Existe uma propriedade chamada box-sizing, que funciona no ie8+. Usando o valor border-box, nós fazemos com que, ao invés de somar os valores de padding do box, ele seja aplicado à largura do mesmo! Vamos aproveitar e aplicar à todos os elementos. Como é uma única propriedade, não há problema em usar o * nesse caso:
1 | * { |
E olha o resultado:

Agora sim, ficou exatamente como eu esperava! Mas eu precisei usar outra propriedade além do float, e ainda usar o width: 100% para ficar correto.
Resultado:
Usar float resolve o problema de conter flutuação? Não sozinho, precisa do box-sizing. Com o box-sizing sim.
É a solução correta? Não. Se estamos flutuando para direita ou esquerda, não faz muito sentido colocar width: 100%.
Conclusão
Não existe uma solução “correta” para isso. Temos essas duas abordagens que estão disponíveis. Podemos usar qualquer uma delas.
Em minha opinião, a que melhor funciona é a do float com box-sizing. Apesar de você precisar flutuar sempre os containers principais, eu penso que é muito mais fácil fazer isso do que, depois do layout todo pronto, o designer colocar uma nova feature, onde é necessário conter a flutuação, e você ter que sair flutuando loucamente tudo o que vir pela frente.
Se flutuar somente os containers principais, o que vai ficar dentro deles é muito mais facilmente controlável :)
A solução ideal para isso, na verdade, seria usar flexbox. Se no seu projeto você não precisa se preocupar com o IE, você pode usá-lo hoje mesmo. Chris Coyier, do CSS Tricks, escreveu um excelente artigo falando praticamente tudo sobre Flexbox. Recomendo a leitura ;)
E você: tem alguma técnica diferente para conter a flutuação? Usa alguma das citadas acima Já havia passado por isso, mas não sabia como resolver? Compartilhe conosco nos comentários! :D
Sobre o #1postperday: https://blog.da2k.com.br/2014/12/31/um-post-por-dia/
Tem alguma sugestão para os próximos posts do #1postperday? Deixe ela aqui: https://github.com/fdaciuk/fdaciuk.github.io/issues/1