Box model CSS: controle o tamanho real dos elementos
Entenda content, padding, border e margin, compare content-box com border-box e corrija um cartão que transborda com medidas reais do navegador.
O box model explica por que um elemento com width: 320px pode aparecer com
376 pixels de largura. Ele divide cada caixa em conteúdo, padding, border e
margin, e permite calcular o tamanho antes que a página ganhe rolagem
horizontal.
Vamos medir dois cartões da Livraria Beira-Rio no Google Chrome 151.0.7922.170. A primeira lição da trilha mostrou como os seletores levam uma regra até o elemento; agora a pergunta muda: depois que a regra chegou, quanto espaço esse elemento realmente ocupa?
Uma encomenda tem produto, proteção, caixa e distância
Pense em um livro enviado pelo correio. O livro é o content; o plástico-bolha ao redor é o padding; o papelão que delimita o pacote é o border; e o espaço deixado entre essa encomenda e as outras na prateleira é o margin. Essa é a ordem do centro para fora.
O mapeamento ajuda a localizar cada camada: conteúdo carrega texto ou imagem, padding cria respiro interno, border desenha o limite e margin afasta caixas vizinhas. Mas a comparação física acaba aí. Margens verticais de caixas CSS podem colapsar, e uma caixa pode sobrepor outra ou sair do fluxo; pacotes reais não seguem essas regras do navegador.
Este é o cartão que vamos medir:
<article class="caixa content-box" id="caixa-content">
O Cortiço
</article>As quatro camadas recebem valores explícitos para não depender do estilo padrão do navegador:
.caixa {
width: 320px;
padding: 24px;
border: 4px solid rgb(37 99 235);
margin: 16px;
}
.content-box {
box-sizing: content-box;
}box-sizing: content-box é o modelo padrão. Nesse modelo, width define
apenas a área de conteúdo. O navegador soma 24 pixels de padding e 4 de borda
em cada lado: 320 + 24 + 24 + 4 + 4 = 376.
Use offsetWidth para ler conteúdo, padding e border juntos. Em seguida, some
as margens calculadas para descobrir o espaço horizontal reservado ao redor da
caixa:
const caixa = document.querySelector('#caixa-content');
const estilo = getComputedStyle(caixa);
const espacoComMargens =
caixa.offsetWidth +
Number.parseFloat(estilo.marginLeft) +
Number.parseFloat(estilo.marginRight);
console.log('width no CSS:', estilo.width);
console.log('caixa até a borda:', caixa.offsetWidth);
console.log('caixa com margens:', espacoComMargens);O resultado separa três perguntas que costumam ser misturadas. width vale
320; a caixa visível até a borda vale 376; e o espaço horizontal considerando
as duas margens vale 408. offsetWidth não inclui margin porque a margem está
fora da borda.
Padding não é margin com outro nome
Os dois criam espaço, mas em lugares e com efeitos diferentes. padding fica
dentro da borda, recebe o fundo do elemento e aumenta a área clicável de um
botão. margin fica fora da borda, é transparente e separa aquela caixa das
vizinhas.
Se um botão parece apertado por dentro, ajuste padding. Se dois cartões estão
colados um no outro, ajuste o espaço entre eles — margin pode resolver em fluxo
normal, enquanto gap costuma expressar melhor o espaço em Flexbox e Grid. A
propriedade certa comunica a intenção para quem mantiver o código.
As formas abreviadas seguem o sentido de um relógio:
.produto-card {
/* cima | direita | baixo | esquerda */
padding: 12px 20px 16px 20px;
/* vertical | horizontal */
margin: 24px 16px;
}Quando há quatro valores, leia a partir de cima e gire no sentido horário. Com
dois, o primeiro vale para cima e baixo; o segundo vale para esquerda e
direita. No início, escrever padding-top ou margin-inline pode ser mais
claro que tentar lembrar uma abreviação no meio de uma depuração.
Border-box coloca a proteção dentro da medida
No modelo alternativo, ativado por box-sizing: border-box, o número em
width representa a caixa até a borda. Padding e border continuam existindo,
mas o navegador desconta essas partes da área de conteúdo.
.border-box {
box-sizing: border-box;
width: 320px;
padding: 24px;
border: 4px solid rgb(37 99 235);
margin: 16px;
}Coloque uma caixa content-box e outra border-box lado a lado no código e
rode a mesma medição:
for (const seletor of ['#caixa-content', '#caixa-border']) {
const elemento = document.querySelector(seletor);
const estilo = getComputedStyle(elemento);
const conteudo = elemento.clientWidth - 48; // padding: 24px em cada lado
console.log(seletor, {
width: estilo.width,
offsetWidth: elemento.offsetWidth,
conteudo,
});
}O cartão border-box manteve os 320 pixels visíveis. Sua área de conteúdo ficou
com 264: 320 - 48 de padding e - 8 de border. Não houve desaparecimento de
espaço; houve uma mudança em qual camada o width mede.
Uma base comum de projeto ativa esse cálculo para todos os elementos, incluindo pseudo-elementos:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}A herança deixa a decisão centralizada e ainda permite que uma região troque o modelo de propósito. Não copie o reset como encantamento: ele existe para que “320 pixels” signifique a largura até a borda na maior parte da interface.
O transbordamento que nasce de uma conta incompleta
Agora reproduza o defeito. Um contêiner oferece 340 pixels. O cartão pede 320,
mas usa content-box com 24 pixels de padding e 4 de border em cada lado:
.limite {
width: 340px;
overflow: auto;
}
.estouro {
box-sizing: content-box;
width: 320px;
padding: 24px;
border: 4px solid rgb(185 28 28);
}O width isolado parece caber: 320 é menor que 340. A caixa final não cabe,
porque mede 376. O navegador comprovou o excesso comparando a largura interna
do contêiner com a área que pode ser rolada:
const limite = document.querySelector('.limite');
const estouro = document.querySelector('.estouro');
console.log('contêiner:', limite.clientWidth);
console.log('cartão:', estouro.offsetWidth);
console.log('área rolável:', limite.scrollWidth);
console.log('excesso:', limite.scrollWidth - limite.clientWidth);Uma rolagem horizontal de 36 pixels não é “o CSS ficando maluco”. É a soma correta de uma declaração que mediu só o conteúdo. Corrija a intenção dizendo que o cartão deve ocupar toda a largura disponível até a borda:
.estouro {
box-sizing: border-box;
width: 100%;
padding: 24px;
border: 4px solid rgb(185 28 28);
}No mesmo teste, mudar apenas box-sizing e width eliminou o excesso. Evite
esconder o sintoma com overflow-x: hidden no body; isso corta conteúdo sem
corrigir a caixa que calculou mal o espaço.
Eixos lógicos deixam a caixa acompanhar o texto
margin-left fala de um lado físico. margin-inline-start fala do começo da
linha, que pode mudar conforme a direção da escrita. Para interfaces que podem
ser traduzidas, propriedades lógicas tornam a intenção mais resistente:
.produto-card {
padding-block: 16px;
padding-inline: 24px;
margin-block-end: 20px;
border-inline-start: 4px solid currentColor;
}Em português, inline normalmente corresponde ao eixo horizontal e block ao
vertical. A tradução prática é “respiro no sentido da linha” e “espaço no
sentido dos blocos”, não uma promessa eterna de esquerda e direita.
Sua missão: medir antes e depois
Crie um cupom com largura de 280 pixels, padding de 20 pixels e border de 2
pixels. Comece com content-box, registre offsetWidth, troque para
border-box e registre novamente.
<aside class="cupom" id="cupom">
Use o código LEITURA10
</aside>.cupom {
box-sizing: content-box;
width: 280px;
padding: 20px;
border: 2px dashed currentColor;
}Seu critério de sucesso é prever os dois resultados sem abrir o console e
depois confirmá-los: 324 pixels no primeiro modelo e 280 no segundo. Acrescente
uma margem de 12 pixels em cada lado e explique por que offsetWidth não muda,
embora a caixa precise de mais espaço no layout.
Com o tamanho de cada caixa sob controle, o próximo desafio é distribuir várias delas numa linha. É justamente o papel de Flexbox no CSS. Se uma regra do box model aparece riscada no DevTools, volte à cascata e aos seletores e siga, quando necessário, para especificidade.
Perguntas frequentes
A propriedade width inclui padding e border?
Margin faz parte da largura de um elemento?
Devo usar box-sizing border-box em todo projeto?
Por que width 100% pode causar rolagem horizontal?
Dúvidas e comentários
Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.
Entrar para perguntarÉ o mesmo login gratuito dos cursos.
Nenhuma dúvida por aqui ainda — a primeira pode ser a sua.
Todo o código deste artigo foi executado em Google Chrome 151.0.7922.170, e as saídas exibidas são as reais — como produzimos este conteúdo.
Fontes consultadas
- MDN — CSS box model — developer.mozilla.org
- MDN — Introduction to the CSS box model — developer.mozilla.org
- MDN — box-sizing — developer.mozilla.org
- CSS Box Model Module Level 4 — W3C — w3.org


