Pare de chutar e aprenda como funciona o float: left e float:right e sua trupe

Marco Bruno
CollabCode
Published in
10 min readJun 3, 2017
Se você não quer ler, pode assistir o vídeo :-)

Não dá para aprender o float: left e float: right sem dar uma olhada na sua trupe: clear: left, clear: right, clear: both e overflow: hidden.

Vou tentar aplicar nesse post a mesma didática que aplico nos cursos da formação FrontEnd da Caelum. Espero que dê certo. :-)

Para explicar o float e sua trupe (clear: letf, clear: right, clear: both e overflow: hidden) faremos diferente de um desafio como foi feito nos três posts anteriores sobre: display: inline, display: block e display: inline-block. Neste usaremos as propriedades e em seguida vamos parar um pouco para entender o comportamento delas.

Como vamos ver as coisas funcionando na prática, teremos uns códigos base: HTML e CSS.

Ah! O código final deste post está disponível no Github e Codepen.

HTML (index.html)

<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>
Exemplo de como funciona o float e seus Friends
</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/float.css">
</head>
<body>
<div class="elementExample elementExample_first">
Apenas uma div
</div>
<div class="elementExample elementExample_last">
Apenas outra div
</div>
<p class="elementParagraph">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, sequi doloribus nesciunt sunt suscipit harum, at, officiis commodi voluptates magni laboriosam! Vitae est veritatis vel asperiores voluptatem, nobis facere cupiditate! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, sequi doloribus nesciunt sunt suscipit harum, at, officiis commodi voluptates magni laboriosam! Vitae est veritatis vel asperiores voluptatem, nobis facere cupiditate! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, sequi doloribus nesciunt sunt suscipit harum, at, officiis commodi voluptates magni laboriosam! Vitae est veritatis vel asperiores voluptatem, nobis facere cupiditate!</p></body>
</html>

CSS (reset.css)

* {
margin: 0;
padding: 0;
border: 0;
}
body {
font-family: "Open Sans", sans-serif;
}
ul, ol, li {
list-style: none;
}

CSS (float.css)

.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
}
.elementExample_last {
background-color: #C0392B;
}

Não podemos nos esquecer de colocar os dois arquivos CSS dentro de uma pasta com o nome de css (letras minúsculas).

Por favor, abra o index.html no seu browser (navegador) favorito (sem dúvida nenhuma é o Firefox) e veja se você está com esse resultado:

Estrutura base para o post :-)

Para começarmos a entender como funciona a propriedade float, vamos aplicá-la pra ver o que acontece. Abra o arquivo float.css e adicione a propriedade float: left; dentro do seletor .elementExample_first:

.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: left;
}
.elementExample_last {
background-color: #C0392B;
}

Por favor, salve esse arquivo e em seguida volte ao browser para dar uma atualizada nele. Você terá o seguinte resultado:

Resultado visual com a primeira div com float:left

Caramba! Agora que aplicamos a propriedade float com o valor left na primeira <div>, aconteceu algo muito estranho. Para onde foi a segunda <div> da cor vermelha? Ela sumiu de fato? Sério?

Se você fosse chutar entre duas opções: a primeira <div> foi parar em cima da segunda; a segunda <div> só foi deletada mesmo. O que você chutaria?
Se chutou que a primeira <div> foi parar em cima da segunda você está certo. Mas só para termos certeza disso, vamos aplicar no seletor da primeira <div> (.elementExample_first) a propriedade opacity com o valor 0.2. Para fazermos isso será necessário voltar para o arquivo float.css:

.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: left;
opacity: .2;
}
.elementExample_last {
background-color: #C0392B;
}

Após você salvar o arquivo e atualizar o browser terá o seguinte resultado:

De fato a segunda está embaixo da que aplicamos float:left

Show! O que vai acontecer se também definirmos a segunda <div> com o float:left; ? Vamos voltar ao nosso arquivo float.css para adicionarmos esse comportamento a na segunda <div> e retirar a propriedade opacity:

Resultado visual com as duas divs com float:left

Deixando as duas com float: left;, elas ficaram uma do lado da outra alinhadas à esquerda com o parágrafo à direita. O fato das <div>s estarem uma do lado da outras faz um pouco de sentido dado que o valor do float é left, mas por que o parágrafo foi parar do lado da segunda <div>?

Vamos fazer mais um teste, mudar o valor da propriedade float para right no seletor .elementExample_last:

.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: left;
}
.elementExample_last {
background-color: #C0392B;
float: right;
}
Agora o parágrafo se encaixou entre as divs

Agora esse parágrafo bizarro foi parar no meio. Wat?
Chega de chutar e vamos entender o que está acontecendo. ;-)

Quando aplicamos a propriedade float com o valores left e right, nesse momento o elemento que ganha o float recebe um novo contexto. Logo em seguida ele é posicionado nesse novo contexto o máximo que ele conseguir para o sentido que foi passado para a propriedade float.

Você deve estar se perguntando: o que eu quero dizer com "novo contexto"?

Novo contexto é uma nova camada que fica acima da camada de origem do elemento. Contudo, se você tiver 4 elementos utilizando a propriedade float, não é criado um novo contexto para cada um deles. Os 4 elementos utilizam o mesmo contexto.

E aquela loucura que acontece com o parágrafo?

Toda vez que tivermos um <img> ou um elemento definido com display: inline ou display: inline-block após qualquer tag definida com a propriedade float: left ou float: right, esses elementos se encaixam ao lado do elemento que está flutuando. Ah! Se <img> ou o elemento com display: inline ou display: inline-block não couber ao lado do elemento que está flutuando, ele fica embaixo do elemento que contém a propriedade float.

Obs. Se você não sabe como funciona a propriedade display recomendo você dar uma olhada nesses 3 posts:

Por que o texto dentro do parágrafo está se encaixando ao lado dos elementos que estão flutuando?
Apesar do display do <p> ser block, o display de qualquer texto é inline, portanto o texto não fica embaixo do elemento que está flutuando e sim ao lado.

Show! Esse é básico do funcionamento do float. Mas ainda temos mais alguns pontos para vermos e entendermos.

Vamos voltar no nosso código. Criaremos um <article> que envolverá as duas <div>s e o <p>.

<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>
Exemplo de como funciona o float e seu Friends
</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/float.css">
</head>
<body>
<article class="wrap-elementExample">
<div class="elementExample elementExample_first">
Apenas uma div
</div>
<div class="elementExample elementExample_last">
Apenas outra div
</div>
<p class="elementParagraph">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, sequi doloribus nesciunt sunt suscipit harum, at, officiis commodi voluptates magni laboriosam! Vitae est veritatis vel asperiores voluptatem, nobis facere cupiditate! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, sequi doloribus nesciunt sunt suscipit harum, at, officiis commodi voluptates magni laboriosam! Vitae est veritatis vel asperiores voluptatem, nobis facere cupiditate! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, sequi doloribus nesciunt sunt suscipit harum, at, officiis commodi voluptates magni laboriosam! Vitae est veritatis vel asperiores voluptatem, nobis facere cupiditate!</p>
</article>
</body>
</html>

Agora vamos voltar no float.css para definirmos uma cor de fundo para o article que acabamos de criar:

.wrap-elementExample {
background-color: #27ae60;
}
.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: left;
}
.elementExample_last {
background-color: #C0392B;
float: right;
}

Por favor, volte no seu browser e atualize ele, espero que você esteja com o seguinte:

Eita só o parágrafo ganhou a cor de fundo

Eita! Só o parágrafo ganhou a cor de fundo, mas o background-color foi aplicado no <article> que está envolvendo os 3 elementos. O que está acontecendo?

Nós colocamos as <div>s com a propriedade float: left e float: right e a partir desse momento esses elementos ganham um novo contexto, ou seja, eles não estão no mesmo contexto do pai (tag <article>) deles. O único elemento que está no mesmo contexto que o pai é o parágrafo, por isso que a altura do <article> está apenas com a altura do <p>.

Como fazermos para o <article> considerar as duas <div>s que estão flutuando e contar com elas para definir a sua altura? Para responder essa teremos que ver umas das propriedades da trupe.

Como funciona a overflow: hidden?

Por favor, abra o arquivo float.css e adicione a propriedade overflow com o valor hidden no seletor .wrap-elementExample:

.wrap-elementExample {
background-color: #27ae60;
overflow: hidden;
}
.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: left;
}
.elementExample_last {
background-color: #C0392B;
float: right;
}

Vá até o browser, atualize ele e você terá o seguinte resultado:

Resultado visual quando aplicamos overflow: hidden

Meio mágico, não? Agora que colocamos o overflow: hidden; no <article> que envolve as 2 <div>s e o <p>, o <article> resolveu considerar as <div>s para definir sua altura. Como isso aconteceu? Por que o<artcile> conseguiu ver as duas <div>s que estão em um novo contexto?

A propriedade overflow com o valor hidden, tem o poder de esconder qualquer elemento filho que ultrapasse o tamanho do seu pai.
Mas quando o pai não tem largura ou altura definida, ele se preocupa em levar em consideração a altura e largura dos filhos, ainda que estes estejam no novo contexto.

Legal! O que acontece se definirmos uma altura e largura para o <article>? Esse eu não vou implementar, se você estiver curioso faz aí ;-)

Como funciona a propriedade clear?

Por último, como eu faço para deixar o parágrafo abaixo dos elementos que estão flutuando?
Para resolver essa precisamos usar a propriedade clear. Portanto, abra seu arquivo float.css e crie um novo seletor para a class elementParagraph e dentro dele coloque a clear: left:

.wrap-elementExample {
background-color: #27ae60;
overflow: hidden;
}
.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: left;
}
.elementExample_last {
background-color: #C0392B;
float: right;
}
.elementParagraph {
clear: left;
}

Volte até o browser e de uma atualizada. Espero que você tenha o seguinte resultado:

Resultado visual utilizando o clear: left;

Essa foi fácil! Assim que colocamos um clear: left no nosso parágrafo ele se moveu para baixo dos elementos que estão flutuando.
Vamos fazer uma nova alteração no nosso código e observar um pouco mais:

.wrap-elementExample {
background-color: #27ae60;
overflow: hidden;
}
.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: right;
}
.elementExample_last {
background-color: #C0392B;
float: right;
}
.elementParagraph {
clear: left;
}

Acabamos de alterar o float: left para float: right que está no seletor .elementExample_first. Como de costume, vamos no browser para vermos qual foi o resultado:

clear: left com elemento a sua direira não tem efeito

Eita! Agora o nosso <p> não está mais abaixo das <div>s que estão flutuando. Por que isso está acontecendo?

A propriedade clear é utilizada para limpar o contexto caso tenha um elemento flutuando ao lado esquerdo (left), direito (right) ou ambos (both).

Por isso que o parágrafo não está mais abaixo das <div>s. Para voltar ele para baixo das <div>s o que devemos alterar no nosso código?
É isso aí, se você está pensando em alterar o valor da propriedade de clear de left para right você está no caminho certo:

.wrap-elementExample {
background-color: #27ae60;
overflow: hidden;
}
.elementExample {
width: 200px;
height: 200px;
line-height: 200px;
color: #FFF;
text-transform: uppercase;
text-align: center;
}
.elementExample_first {
background-color: #8E44AD;
float: right;
}
.elementExample_last {
background-color: #C0392B;
float: right;
}
.elementParagraph {
clear: right;
}

Você verá em muitos códigos que a galera utiliza a clear com o valor both, sem pensar porque se tiver qualquer elemento flutuando tanto à direita quanto à esquerda, o contexto será limpo.

Acho que isso é tudo que eu sei sobre a propriedade float. A maior parte do que eu aprendi eu devo ao William Bruno que me passou o seu conhecimento no tempo que trabalhamos juntos na Locaweb.

Felizmente, hoje graças à Caelum, Joviane Jardim e Alberto Souza sei passar esse conhecimento de uma forma mais feliz. Obrigado por me ensinar a ensinar ;-)

Se você sabe algo a mais sobre o float que eu esqueci de falar, por favor não deixe de colocar no comentário, sempre é bom aprender mais.
Dúvidas também são legais, não deixe de perguntar seja no comentário ou se preferir pode me adicionar nas redes sociais, você vai conseguir me achar por MarcoBrunoBR. Eu gosto de usar o Telegram :-)

--

--

Marco Bruno
CollabCode

Migrei de palhaço para Dev. Front-End/UX e agora eu trabalho como streamer de código