Objetivo: Entender por que
floatnão é eficiente para criar layouts de colunas com bordas, e como o Flexbox resolve esse problema de forma elegante.
O modelo de caixa (box model) do CSS define como o tamanho de um elemento é calculado. Por padrão (box-sizing: content-box), a largura declarada representa apenas o conteúdo — bordas e padding são somados por fora.
┌─────────────────────────────────────────┐
│ MARGIN │
│ ┌───────────────────────────────────┐ │
│ │ BORDER │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ PADDING │ │ │
│ │ │ ┌───────────────────────┐ │ │ │
│ │ │ │ CONTEÚDO │ │ │ │
│ │ │ │ (width declarada) │ │ │ │
│ │ │ └───────────────────────┘ │ │ │
│ │ └─────────────────────────────┘ │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
Tamanho real = width + padding-left + padding-right
+ border-left + border-right
Duas divs com float: left e width: 50%. Parece funcionar:
.container {
overflow: hidden; /* clearfix */
}
.div1, .div2 {
float: left;
width: 50%;
box-sizing: content-box; /* padrão */
}Resultado visual:
┌──────────────────────────────────────────────────────┐
│ .container │
│ ┌────────────────────────┬────────────────────────┐ │
│ │ div 1 │ div 2 │ │
│ │ 50% │ 50% │ │
│ └────────────────────────┴────────────────────────┘ │
└──────────────────────────────────────────────────────┘
Cálculo: 50% + 50% = 100% ✓ → Layout OK
Adicionamos border: 4px solid. O layout quebra!
.div1, .div2 {
float: left;
width: 50%;
border: 4px solid; /* ← problema aqui */
/*
box-sizing: content-box (padrão)
largura real = 50% + 4px + 4px = 50% + 8px
total = 100% + 16px → OVERFLOW!
*/
}Resultado visual:
┌──────────────────────────────────────────────────────┐
│ .container │
│ ╔════════════════════════╗ │
│ ║ div 1 ║ │
│ ║ 50% + 8px de borda ║ │
│ ╚════════════════════════╝ │
│ ╔════════════════════════╗ │
│ ║ div 2 ║ ← QUEBROU! │
│ ║ 50% + 8px de borda ║ (empurrada │
│ ╚════════════════════════╝ para baixo) │
└──────────────────────────────────────────────────────┘
Cálculo: (50% + 8px) + (50% + 8px) = 100% + 16px ✗
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
estoura o container!
⚠️ Por quê? Combox-sizing: content-box, a borda é adicionada além da largura de 50%. Cada div passa a ocupar50% + 8px, e as duas juntas ultrapassam 100%.
Uma solução parcial: incluir a borda dentro da largura declarada.
.div1, .div2 {
float: left;
width: 50%;
border: 4px solid;
box-sizing: border-box; /* borda entra nos 50% */
}
/* Ainda precisamos de clearfix no pai! */
.container::after {
content: "";
display: table;
clear: both;
}Resultado visual:
┌──────────────────────────────────────────────────────┐
│ .container │
│ ╔═══════════════════════╦════════════════════════╗ │
│ ║ div 1 ║ div 2 ║ │
│ ║ 50% (borda inclusa) ║ 50% (borda inclusa) ║ │
│ ╚═══════════════════════╩════════════════════════╝ │
└──────────────────────────────────────────────────────┘
Cálculo: 50% + 50% = 100% ✓ → Layout OK agora
Mas ainda exige:
┌─ Problemas que persistem com float ──────────────────┐
│ │
│ ❌ Lembrar de box-sizing: border-box em todo lugar │
│ ❌ Clearfix manual no elemento pai │
│ ❌ Sem gap/espaçamento nativo entre colunas │
│ ❌ Sem alinhamento vertical automático │
│ ❌ Float foi projetado para texto, não para layout │
│ │
└──────────────────────────────────────────────────────┘
Com display: flex no container, as divs filhas se comportam como flex items. Bordas, gaps e alinhamento funcionam naturalmente — sem gambiarras.
.container {
display: flex;
gap: 12px; /* espaço entre as divs */
}
.div1, .div2 {
flex: 1; /* divide o espaço igualmente */
border: 4px solid;
/* sem float, sem clearfix, sem box-sizing manual */
}Resultado visual:
┌──────────────────────────────────────────────────────┐
│ .container │
│ ╔══════════════════╗ gap ╔══════════════════╗ │
│ ║ ║◄──12px─►║ ║ │
│ ║ div 1 ║ ║ div 2 ║ │
│ ║ flex: 1 ║ ║ flex: 1 ║ │
│ ║ ║ ║ ║ │
│ ╚══════════════════╝ ╚══════════════════╝ │
└──────────────────────────────────────────────────────┘
O Flexbox distribui o espaço DEPOIS de considerar
bordas e gaps — sem overflow, sem cálculo manual.
Como o Flexbox distribui o espaço:
Espaço disponível do container
│
├─ subtrai o gap (12px)
│
└─ divide o restante igualmente entre os flex items
(flex: 1 = "ocupe uma fração igual do espaço livre")
Resultado: cada div tem exatamente a largura correta,
com borda já incluída na conta do Flexbox.
┌────────────────────────────┬────────────────────────────┐
│ FLOAT │ FLEXBOX │
├────────────────────────────┼────────────────────────────┤
│ ❌ Clearfix no pai │ ✅ Container limpo │
│ ❌ Borda quebra a largura │ ✅ Bordas respeitadas │
│ ❌ box-sizing manual │ ✅ Distribuição automática│
│ ❌ Sem gap nativo │ ✅ gap: 12px funciona │
│ ❌ Sem alinhamento vertical│ ✅ align-items: center │
│ ❌ Criado para texto/imagem│ ✅ Criado para layout │
└────────────────────────────┴────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ │
│ Use float → apenas para envolver texto em imagens │
│ │
│ Use Flexbox → para qualquer layout de colunas/linhas │
│ Use Grid → para layouts bidimensionais complexos │
│ │
└──────────────────────────────────────────────────────────┘
<!-- HTML -->
<div class="container">
<div class="coluna">Coluna 1</div>
<div class="coluna">Coluna 2</div>
</div>/* CSS moderno com Flexbox */
.container {
display: flex;
gap: 16px;
align-items: stretch; /* mesma altura nas colunas */
}
.coluna {
flex: 1;
padding: 1rem;
border: 2px solid #ccc;
border-radius: 8px;
/* Sem float. Sem clearfix. Sem box-sizing manual. */
}Tutorial de WebDesign — Box Model, Float e Flexbox