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
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Float ou Overflow</title>
</head>
<body>
<div>
<img src="http://placehold.it/1x1" width="200" height="200" alt="" />
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cumque natus, corporis quae molestiae eum facilis mollitia temporibus expedita ipsam sequi culpa sunt, fugiat. Porro velit dolore quo, dolorem, quia earum nihil cumque inventore placeat vero ullam, neque ad quae, molestias deleniti. Quas facilis incidunt ipsa facere inventore impedit quae debitis?</p>
</div>
</body>
</html>

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
2
3
4
5
6
<style>
div {
background: red;
padding: 15px;
}
</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
2
3
img {
float: right;
}

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
2
3
4
5
div {
background: red;
overflow: hidden;
padding: 15px;
}

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
2
3
4
<div>
<span class="badge"></span>
<img src="http://placehold.it/1x1" width="200" height="200" alt="" />
...

E vamos posicioná-lo no canto superior esquerdo do box:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
div {
background: red;
overflow: hidden;
padding: 15px;
position: relative;
}

.badge {
background: purple;
border-radius: 50px;
height: 50px;
left: -25px;
position: absolute;
top: -25px;
width: 50px;
}

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
2
3
4
5
6
div {
background: red;
float: left;
padding: 15px;
position: relative;
}

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
2
3
4
5
6
7
div {
background: red;
float: left;
padding: 15px;
position: relative;
width: 100%;
}

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
2
3
4
5
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

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