O que é o box model?
O box model do CSS é o conceito fundamental por trás de todo layout na web. Ele descreve como cada elemento HTML é renderizado como uma caixa retangular com quatro camadas distintas: content, padding, border e margin. Esteja você estilizando um parágrafo simples ou construindo um dashboard complexo, o box model determina quanto espaço um elemento ocupa e como ele se relaciona com seus vizinhos.
Pense nisso como a moldura de um quadro. A imagem em si é o content. A margem interna (passe-partout) ao redor dela é o padding. A moldura é a border. E o espaço entre essa moldura e a próxima na parede é a margin. Todo elemento em uma página web funciona exatamente assim — caixas aninhadas dentro de outras caixas.
As quatro camadas
Content (Conteúdo) é a camada mais interna — o texto, imagem, vídeo ou outra mídia que o elemento contém. Seu tamanho é definido com width e height (ou pelo próprio conteúdo, caso estes não sejam especificados).
Padding (Preenchimento) fica entre o conteúdo e a borda. Ele adiciona um espaço interno ao elemento para que o texto não fique apertado contra as extremidades. O padding é transparente por padrão, portanto, a cor de fundo ou a imagem do elemento aparecem através dele.
Border (Borda) envolve o padding e o conteúdo. Ela possui largura, estilo e cor. As bordas podem ser decorativas ou estruturais — elas são a extremidade visível que separa o elemento do mundo exterior.
Margin (Margem) é a camada mais externa. Ela empurra outros elementos para longe. Diferente do padding, a margem é sempre transparente e fica fora da borda do elemento. As margens são a principal ferramenta para controlar o espaçamento entre elementos.
box-sizing: content-box vs border-box
A propriedade box-sizing altera a forma como o navegador interpreta width e height.
Com o valor padrão, content-box, a largura (width) e a altura (height) que você define aplicam-se apenas à área de conteúdo. O padding e a borda são adicionados por cima. Portanto, um div com width: 200px, padding: 20px e uma borda de 4px na verdade é renderizado com 248px de largura. Isso é contra-intuitivo e é a fonte mais comum de bugs de layout para iniciantes.
Com border-box, a largura e a altura já incluem o padding e a borda. O mesmo div com width: 200px, padding: 20px e uma borda de 4px permanece com exatamente 200px de largura — a área de conteúdo diminui para abrir espaço. É assim que a maioria dos desenvolvedores espera que o dimensionamento funcione, e é por isso que um reset global como este é prática padrão:
/* reset.css */
*,
*::before,
*::after {
box-sizing: border-box;
}
O Border-box torna os layouts previsíveis. Você define uma largura e o elemento a respeita. Não há necessidade de fazer cálculos mentais para descobrir por que suas colunas estão mais largas do que o esperado. Use-o em todo lugar e esqueça as dores de cabeça.
Block vs inline vs inline-block
Todo elemento possui um comportamento de display padrão que controla como ele participa do layout.
Elementos Block começam em uma nova linha e se expandem para preencher toda a largura do elemento pai. Eles são empilhados verticalmente. Exemplos incluem div, p, h1 até h6, section, article, header, footer e ul. Elementos block aceitam width, height, margin em todos os lados e padding em todos os lados.
Elementos Inline fluem dentro do texto sem quebrar a linha. Eles ocupam apenas a largura necessária para o seu conteúdo. Exemplos incluem span, a, strong, em, img e code. Elementos inline ignoram width e height, e margin e padding verticais não afetam o layout ao redor — eles se deslocam visualmente, mas não empurram outros elementos.
Elementos Inline-block são um híbrido. Eles fluem inline como texto, mas se comportam como blocks internamente — aceitando width, height, margin e padding em todos os lados. Links de navegação, badges e tags são casos de uso clássicos. Eles permanecem no fluxo do texto, mas oferecem controle total sobre dimensionamento e espaçamento.
| Propriedade | Block | Inline | Inline-block |
|---|---|---|---|
| Começa em nova linha | Sim | Não | Não |
| Largura/altura | Sim | Não | Sim |
| Margem/padding vertical | Sim | Não (apenas visual) | Sim |
| Margem/padding horizontal | Sim | Sim | Sim |
A propriedade display
A propriedade display é a ferramenta de layout mais poderosa do CSS. Ela controla não apenas o comportamento do box model, mas também como um elemento participa dos algoritmos de layout.
Os valores mais comuns:
block— caixa de largura total, empilhada verticalmente.inline— flui com o texto, sem dimensionamento de box-model.inline-block— fluxo inline com dimensionamento de box-model.none— remove o elemento completamente do layout. Ele não ocupa espaço e não é renderizado.flex— transforma o elemento em um flex container. Os filhos tornam-se flex items com controle de layout unidimensional.grid— transforma o elemento em um grid container. Os filhos são posicionados em um grid bidimensional.inline-flex— flex container que flui inline.inline-grid— grid container que flui inline.
O CSS moderno oferece flex e grid para layout, mas entender block e inline ainda é essencial, pois eles são a base sobre a qual o flex e o grid são construídos. Todo elemento sem um valor de display explícito retorna para block ou inline, dependendo do tipo do elemento.
Cálculos de largura e altura
A forma como a largura e a altura são calculadas depende inteiramente de box-sizing.
Com content-box:
Actual width = width + padding-left + padding-right + border-left + border-right
Actual height = height + padding-top + padding-bottom + border-top + border-bottom
Com border-box:
Actual width = width (padding and border are included)
Actual height = height (padding and border are included)
Uma consequência prática: com content-box, definir width: 100% em um elemento com padding ou border causará overflow horizontal. Com border-box, funciona como esperado. Este é um dos argumentos mais fortes para sempre utilizar border-box.
Para dimensionamento dentro de um container, lembre-se que porcentagens para width referem-se à largura do conteúdo do pai (mesmo com border-box), enquanto porcentagens para height exigem que o pai tenha uma altura explícita — caso contrário, a porcentagem é tratada como auto.
Overflow e rolagem
Quando o conteúdo é maior que o seu container, a propriedade overflow decide o que acontece.
overflow: visible(padrão) — o conteúdo transborda para fora da caixa. Ele fica visível, mas pode sobrepor elementos irmãos.overflow: hidden— o conteúdo é cortado na borda da caixa. Não há barra de rolagem nem forma de ver o restante.overflow: scroll— uma barra de rolagem aparece, independentemente de ser necessária ou não.overflow: auto— uma barra de rolagem aparece apenas quando o conteúdo transborda. Esta costuma ser a melhor escolha.overflow-xeoverflow-ypermitem controlar o overflow horizontal e vertical de forma independente.
O overflow é especialmente importante em containers com largura fixa, modais, blocos de código e qualquer elemento cujo conteúdo possa crescer. Sem ele, é comum surgirem barras de rolagem horizontais inesperadas na página.
Colapso de margem (Margin collapse)
As margens verticais possuem uma particularidade que surpreende quase todo iniciante: elas colapsam. Quando duas margens verticais se tocam, a maior delas prevalece em vez de as duas serem somadas.
/* style.css */
.box-a { margin-bottom: 30px; }
.box-b { margin-top: 20px; }
/* The gap between them is 30px, not 50px */
O colapso de margem acontece em três situações:
- Irmãos adjacentes — a margem inferior de um e a margem superior do próximo se fundem.
- Pai e primeiro filho — a margem superior do pai colapsa com a margem superior do seu primeiro filho (se o pai não tiver borda, padding ou conteúdo para separá-los).
- Pai e último filho — o mesmo que acima, mas para a parte inferior.
O colapso de margem nunca acontece com:
- Margens horizontais.
- Itens flex e grid (o box model é diferente dentro desses containers).
- Elementos com
overflowdefinido como qualquer valor diferente devisible. - Elementos com
borderoupaddingque separam as margens.
Entender o colapso de margem evita o problema do “por que este espaço está com o tamanho errado”, que leva desenvolvedores a adicionarem padding arbitrário ou margens negativas.
Posicionamento: static, relative, absolute, fixed, sticky
A propriedade position remove um elemento do fluxo normal do documento ou modifica a sua posição nele.
static é o padrão. O elemento permanece no fluxo normal, e top, right, bottom, left e z-index não têm efeito.
relative mantém o elemento no fluxo, mas permite deslocá-lo com top, right, bottom e left. O espaço original é preservado — é como se você desse um “empurrão” visual no elemento, mantendo o seu espaço no layout.
absolute remove completamente o elemento do fluxo. Ele é posicionado em relação ao ancestral posicionado mais próximo — qualquer ancestral com position definido como relative, absolute, fixed ou sticky. Se nenhum ancestral assim existir, ele utiliza a viewport. Elementos absolutos não afetam o layout de irmãos ou pais.
fixed também remove o elemento do fluxo, mas o posiciona em relação à viewport. Ele permanece no mesmo lugar quando a página é rolada. Use-o para headers fixos, botões de ação flutuantes e modais que devem permanecer visíveis.
sticky é um híbrido. O elemento rola normalmente até atingir um limite (top, right, bottom ou left), então ele “gruda” no lugar. É a substituição moderna para listeners de scroll em JavaScript. Barras de navegação que ficam no topo enquanto você rola a página são o caso de uso clássico.
/* style.css */
.sticky-nav {
position: sticky;
top: 0;
z-index: 10;
}
Z-index e contexto de empilhamento
Quando elementos se sobrepõem, o z-index determina qual deles aparece no topo. Ele funciona apenas em elementos posicionados — aqueles com position definido como qualquer valor diferente de static.
Mas o z-index não é um número global simples. Ele cria ou participa de um stacking context (contexto de empilhamento). Um stacking context é uma camada autocontida que encapsula seus filhos. Um filho com z-index: 9999 dentro de um stacking context com z-index: 1 nunca aparecerá acima de um elemento com z-index: 2 no contexto pai.
Stacking contexts são criados por:
- Elementos com
positionez-indexdiferentes deauto. - Elementos com
opacitymenor que 1. - Elementos com
transform,filter,backdrop-filterouperspective. - Elementos com
isolation: isolate. - Elementos dentro de um container flex ou grid com um
z-index.
Entender os stacking contexts é a chave para resolver problemas de “o z-index não funciona”. A solução quase nunca é usar um número maior — mas sim entender em qual stacking context o seu elemento está inserido.
Melhores práticas de layout
- Sempre use
box-sizing: border-boxglobalmente. Isso elimina toda uma classe de bugs de dimensionamento. - Evite
width: 100%com padding em elementos content-box. Use border-box em vez disso. - Prefira
max-widthawidthpara conteúdos que não devem se expandir excessivamente. - Use
margin: autopara centralização horizontal dentro de containers de bloco. - Use
overflow: autoem vez deoverflow: hiddenquando desejar barras de rolagem para conteúdo que transborda (overflow). - Evite definir
heightfixos para containers com conteúdo dinâmico — deixe-os crescer conforme o conteúdo. - Para espaçamento vertical, fique atento ao colapso de margens (margin collapse). Use gap em flex/grid ou padding no elemento pai.
- Nunca use
position: absolutepara layout geral — isso quebra o fluxo do documento e dificulta o design responsivo. - Use
position: stickyem vez de JavaScript para headers e sidebars que reagem ao scroll. - Mantenha os contextos de empilhamento (stacking contexts) rasos. Valores de
z-indexsobrepostos em componentes profundamente aninhados geram confusão. - Teste os layouts em múltiplas larguras. O box model se comporta de maneira diferente quando o viewport diminui.
Erros comuns
- Esquecer de definir
box-sizing: border-boxe obter larguras inesperadas. - Usar
widthem elementos inline e questionar por que nada muda. - Aplicar
marginem elementos inline e não obter o espaçamento esperado. - Usar
position: absolutesem um elemento pai posicionado, fazendo com que os elementos “voem” para o canto da viewport. - Confusão quando
z-indexnão funciona — geralmente é um problema de stacking context. - Surpresa com o margin collapse entre elementos pai e filho.
- Definir uma altura fixa em um container e ver o conteúdo transbordar (overflow) de forma invisível.
- Usar
overflow: hiddenpara “corrigir” o layout quando o problema real é o dimensionamento incorreto.
Quando usar o box model vs Flexbox ou Grid
O box model não é um sistema de layout por si só — ele é a base sobre a qual todos os layouts CSS são construídos. Flexbox e Grid não substituem o box model; eles o utilizam. Cada flex item e célula de grid ainda possui content, padding, border e margin.
Use o box model diretamente para:
- Controlar o espaçamento dentro e ao redor de elementos individuais.
- Definir tamanhos explícitos para cards, botões, inputs e containers.
- Entender por que elementos sofrem overflow ou não cabem em seus pais.
Use Flexbox quando precisar alinhar e distribuir itens ao longo de um único eixo — barras de navegação, linhas de cards, centralização de conteúdo.
Use Grid quando precisar de um layout bidimensional com linhas e colunas — estruturas de página, dashboards, galerias de imagens.
Os melhores desenvolvedores CSS recorrem primeiro ao box model para entender o que está acontecendo e, em seguida, aplicam flex ou grid para layouts de nível superior. Aprender o box model não é algo separado de aprender layouts modernos — é o pré-requisito que faz tudo o mais fazer sentido.