Box-sizing: content-box vs border-box

Entenda a diferença entre os modelos de caixa e como border-box simplifica o layout.

Você já aprendeu que, no Box Model padrão, o padding e a border aumentam o tamanho total de um elemento além da sua width e height definidas. Isso pode ser um pouco confuso e dificultar o cálculo preciso de layouts, especialmente quando se trabalha com porcentagens ou em designs responsivos.

É para resolver essa questão que existe a propriedade box-sizing. Ela define como a largura e a altura de um elemento são calculadas, controlando se o padding e a border são incluídos ou não nessas dimensões.

Pense no box-sizing como uma "régua" que você usa para medir suas caixas. Com a régua padrão (content-box), você mede apenas o espaço do conteúdo. Com a régua alternativa (border-box), você mede a caixa inteira, incluindo o acolchoamento e as paredes.

Os Dois Modelos de box-sizing

Existem dois valores principais para a propriedade box-sizing:

1. content-box (Padrão do Navegador)

  • Como funciona: Este é o comportamento padrão do Box Model. Quando você define width e height, elas se referem apenas à área do conteúdo.

  • Cálculo do tamanho total:

    • Largura Total = width + padding-left + padding-right + border-left-width + border-right-width
    • Altura Total = height + padding-top + padding-bottom + border-top-width + border-bottom-width
  • Desvantagem: Se você tem um elemento com width: 100%; e adiciona padding ou border, ele ultrapassará os 100% da largura do pai, causando problemas de layout. Isso exige cálculos manuais constantes para ajustar a largura.

    [[google images: CSS content-box diagram]]

2. border-box (O Modelo Simplificado)

  • Como funciona: Quando você define width e height, elas se referem ao conteúdo + padding + border. Ou seja, o padding e a border são incluídos dentro da largura e altura especificadas.

  • Cálculo do tamanho total:

    • Largura Total = width (que já inclui padding e border)
    • Altura Total = height (que já inclui padding e border)
  • Vantagem: Simplifica muito o cálculo de layouts. Se você define width: 100%; e adiciona padding e border, o elemento não ultrapassará os 100% da largura do pai. O espaço do conteúdo será reduzido para acomodar o padding e a border.

  • Uso: É amplamente considerado uma melhor prática e é o modelo preferido pela maioria dos desenvolvedores modernos.

    [[google images: CSS border-box diagram]]

Por que border-box é tão popular?

Imagine que você quer criar duas colunas que ocupem 50% da largura do seu contêiner, com um padding interno e uma border.

  • Com content-box: Você teria que fazer width: calc(50% - 20px - 4px); (se o padding fosse 10px de cada lado e a borda 2px de cada lado), o que é complicado e propenso a erros.
  • Com border-box: Você simplesmente faz width: 50%; padding: 10px; border: 2px solid black;. O navegador se encarrega de ajustar a área do conteúdo para que o elemento total não ultrapasse os 50%.

Como aplicar border-box

A forma mais comum e recomendada de aplicar border-box é usando o "universal selector" (*) e o "pseudo-elemento ::before e ::after" para garantir que todos os elementos do seu projeto (e seus pseudo-elementos) usem esse modelo:

/* Reset universal para border-box */
html {
  box-sizing: border-box;
}
*, *::before, *::after {
  box-sizing: inherit; /* Herda o box-sizing do html */
}

Com essa regra, você define box-sizing: border-box; no html e faz com que todos os outros elementos herdem esse comportamento. Isso garante consistência em todo o seu projeto.

Exemplo Prático:

<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <title>Box-sizing</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
      background-color: #f4f4f4;
    }

    .container {
      width: 600px;
      border: 2px solid #333;
      padding: 10px;
      margin-bottom: 30px;
      background-color: #fff;
      display: flex; /* Para colocar as caixas lado a lado */
      justify-content: space-around;
    }

    .box {
      width: 250px; /* Largura definida */
      height: 100px;
      padding: 20px; /* Padding de 20px em todos os lados */
      border: 5px solid blue; /* Borda de 5px */
      background-color: lightblue;
      text-align: center;
      line-height: 100px;
      font-weight: bold;
      color: #333;
      margin: 10px;
    }

    /* Exemplo com content-box (padrão) */
    .content-box-example {
      box-sizing: content-box; /* Explícito, mas é o padrão */
      background-color: lightcoral;
      border-color: red;
    }

    /* Exemplo com border-box */
    .border-box-example {
      box-sizing: border-box;
      background-color: lightgreen;
      border-color: green;
    }

    /* Reset universal para border-box para o segundo container */
    .container-border-box {
      box-sizing: border-box; /* Define para o container */
    }
    .container-border-box .box {
      box-sizing: inherit; /* Herda do container */
    }

    .col {
      width: 50%; /* 50% da largura do pai */
      padding: 15px;
      border: 1px solid #555;
      background-color: #e0e0e0;
      margin: 5px;
      text-align: center;
    }
  </style>
</head>
<body>
  <h2>Comparação: `content-box` vs `border-box`</h2>

  <div class="container">
    <div class="box content-box-example">
      `content-box` <br> (Largura total: 250 + 2*20 + 2*5 = 300px)
    </div>
    <div class="box border-box-example">
      `border-box` <br> (Largura total: 250px)
    </div>
  </div>

  <h2>Exemplo Prático: Colunas com `border-box`</h2>
  <p>Com `box-sizing: border-box;` aplicado globalmente, criar colunas com porcentagens e padding/border é muito mais fácil.</p>
  <div class="container container-border-box">
    <div class="col">
      Coluna 1 (50% width)
    </div>
    <div class="col">
      Coluna 2 (50% width)
    </div>
  </div>
</body>
</html>

Resultado: Inspecione os elementos com as ferramentas de desenvolvedor.

  • No content-box-example, você verá que a largura total do elemento é maior que os 250px definidos, pois o padding e a border são adicionados.
  • No border-box-example, a largura total do elemento será exatamente 250px, e o espaço do conteúdo será ajustado para acomodar o padding e a border.
  • No exemplo das colunas, observe como as duas colunas de width: 50%; se encaixam perfeitamente lado a lado quando border-box está ativo, sem ultrapassar a largura do contêiner.

Boas Práticas:

  • Use box-sizing: border-box;: É a recomendação da maioria dos desenvolvedores e frameworks modernos. Ele simplifica o cálculo de layouts e torna o CSS mais intuitivo.
  • Reset Universal: Aplique o reset universal (html { box-sizing: border-box; } *, *::before, *::after { box-sizing: inherit; }) no início do seu CSS para garantir que todos os elementos do seu projeto se comportem da mesma forma.
  • Entenda a Diferença: Mesmo usando border-box, é crucial entender como content-box funciona, pois é o padrão do navegador e você pode encontrá-lo em códigos antigos ou em situações específicas.

Dominar box-sizing é um divisor de águas no desenvolvimento front-end, tornando o trabalho com layouts muito mais previsível e menos propenso a erros.