Skip to content

Instantly share code, notes, and snippets.

@marcellobenigno
Created March 19, 2026 10:06
Show Gist options
  • Select an option

  • Save marcellobenigno/1d316b67c89ce1b5fda9861557eab0f3 to your computer and use it in GitHub Desktop.

Select an option

Save marcellobenigno/1d316b67c89ce1b5fda9861557eab0f3 to your computer and use it in GitHub Desktop.

Box Model + Float vs. Flexbox

Objetivo: Entender por que float não é eficiente para criar layouts de colunas com bordas, e como o Flexbox resolve esse problema de forma elegante.


O que é o Box Model?

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

Etapa 1 — Float sem bordas

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

Etapa 2 — Float com bordas 💥

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ê? Com box-sizing: content-box, a borda é adicionada além da largura de 50%. Cada div passa a ocupar 50% + 8px, e as duas juntas ultrapassam 100%.


Etapa 3 — "Correção" com box-sizing: border-box

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 │
│                                                      │
└──────────────────────────────────────────────────────┘

Etapa 4 — Flexbox resolve tudo ✅

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.

Resumo Comparativo

┌────────────────────────────┬────────────────────────────┐
│        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     │
└────────────────────────────┴────────────────────────────┘

Regra de Ouro

┌──────────────────────────────────────────────────────────┐
│                                                          │
│   Use float   →  apenas para envolver texto em imagens   │
│                                                          │
│   Use Flexbox →  para qualquer layout de colunas/linhas  │
│   Use Grid    →  para layouts bidimensionais complexos   │
│                                                          │
└──────────────────────────────────────────────────────────┘

Código Final Recomendado

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment