CSS Box Model: corrigindo elementos com tamanhos inesperados

demenezes

deMenezes

Posted on July 13, 2022

CSS Box Model: corrigindo elementos com tamanhos inesperados

O Box Model define as 4 partes de um elemento HTML: conteúdo, padding, border e margin. Só isso seria simples, se não fosse o box-sizing interferindo no tamanho dos elementos. Para se aprofundar em front-end, é preciso entender também sobre o box-sizing e o impacto dele no funcionamento de width.

  • Entenda de Box Model
  • padding é o espaço entre o conteúdo do elemento e sua borda
  • margin é a distância entre dois elementos
  • A propriedade width muda seu comportamento dependendo do valor da propriedade box-sizing
  • De preferência, sempre insira o trecho * { box-sizing: border-box; } no CSS de todos os seus projetos

HTML é um monte de caixinha dentro de caixinha dentro de caixinha... (e contando).

E essas caixinhas são representadas pelo Box Model. Ele não é uma propriedade CSS, mas sim um conceito muito importante. Entender de Box Model pode evitar algumas dores de cabeça, enquanto você desenvolve seus sites.

Box Model mostrando as medidas do conteúdo, padding, border e margin

Vou começar com uma dica bem simples, porém essencial antes de avançar para os próximos capítulos.

Padding e Margin não são a mesma coisa

Agora pode parecer óbvio.

Mas no início dos meus estudos, eu achava que padding e margin eram praticamente a mesma coisa (chora Box Model).

Eu sempre pensava que o objetivo era o mesmo: criar um espaço entre os elementos:

<button class="button--primary">
  OK
</button>

<button class="button--secondary">
  CANCEL
</button>
Enter fullscreen mode Exit fullscreen mode
.button--primary,
.button--secondary {
  border: none;
  background-color: transparent;
  padding: 0;
  margin: 0;
}

.button--primary {
  padding-right: 20px;
  margin-right: 20px;
}
Enter fullscreen mode Exit fullscreen mode

Tanto o padding quanto o margin aplicados no .button--primary inserem um espaço entre os botões.

Veja o padding na cor verde e o margin na cor laranja:

Dois botões com padding e margin entre eles. Os botões não possuem borda

Porém, quando adiciono uma borda nos botões, a diferença entre eles fica mais clara:

.button--primary,
.button--secondary {
  border: 5px solid black; /* aqui */
  background-color: transparent;
  padding: 0;
  margin: 0;
}

.button--primary {
  padding-right: 20px;
  margin-right: 20px;
}
Enter fullscreen mode Exit fullscreen mode

Dois botões com padding e margin entre eles. Os botões possuem borda

Pense no padding como uma alteração mais individual, já que ele adiciona um preenchimento entre o conteúdo do elemento e a borda do elemento (assim como um botox que preenche o lábio).

Por outro lado, o margin é mais usado quando você olha para o layout, uma vez que ele adiciona um espaço entre a borda e o elemento vizinho (ou o canto da janela). É como se fosse o distanciamento social que as pessoas deveriam ter feito na pandemia.

Após compreender essas duas propriedades, fica mais fácil entender o que é o Box Model (e a importância dele).

Box Model

Imagem ilustrativa de um Box Model

Pense que cada elemento HTML é uma caixa que possui:

  • Conteúdo (azul): texto, imagem, vídeo ou outro elemento HTML
  • Padding (verde): preenchimento entre o conteúdo e a borda
  • Borda (amarela): controlada pela propriedade border do CSS
  • Margin (laranja): distância entre o elemento analisado e seu vizinho

Entender o Box Model pode facilitar muito a sua vida e te ajudar a desenvolver sites com menos dores de cabeça.

Então para saber o tamanho de um elemento basta somar o seu conteúdo, padding, borda e margin, certo? Bem, nem sempre.

Box-sizing e seu impacto no Box Model

O tamanho de cada caixinha (definido em width)depende da propriedade box-sizing.

Segundo a W3C, Ela possui dois valores:

  1. Content-box: o tamanho da caixa é o resultado de width + padding + margin
  2. Border-box: o tamanho da caixa é definido apenas pela propriedade width

Veja um exercício básico. Qual será a largura dessa div, dado que seu conteúdo tem largura de 50px?

div {
  display: inline-block;
  padding: 30px;
  border: 5px solid black;
}
Enter fullscreen mode Exit fullscreen mode

O cálculo é feito da seguinte forma:

conteúdo + padding-left + padding-right + border-left + border-right

Ou seja

50 + 30 + 30 + 5 + 5 = 120px

Agora, algo estranho acontece quando acrescento a propriedade width:

div {
  display: inline-block;
  padding: 30px;
  border: 5px solid black;
  width: 300px; /* plim */
}
Enter fullscreen mode Exit fullscreen mode

Qual será a nova largura:

  • 120px?
  • 300px?
  • 370px?

Estranhamente, o Box Model define que será 370px, e isso é responsabilidade da propriedade box-sizing, pois por padrão ela possui o valor content-box.

Assim, a linha width: 300px irá modificar a largura do conteúdo. Mas falta somar o padding e border ao seu tamanho total.

conteúdo + padding-left + padding-right + border-left + border-right

Ou seja

300 + 30 + 30 + 5 + 5 = 370px

Isso causa uma grande confusão, já que o elemento não tem 300px de largura, apesar de isso estar explícito no CSS.

A forma de resolver isso é com esse trecho de código que é quase um mantra entre os front-ends:

* {
  box-sizing: border-box;
}
Enter fullscreen mode Exit fullscreen mode

Isso altera a propriedade box-sizing de todos os elementos para o valor border-box.

A partir de agora, o navegador irá incluir padding e borda no valor da propriedade width, e no caso irá totalizar sempre os 300px.

Todos os cálculos foram feitos sem somar o tamanho das margens. Ela é válida para fins de layout, mas o navegador não considera ela no cálculo do tamanho total.

Callback

Defina o quanto antes no seu projeto o * { box-sizing: border-box; }, para não ter problema no tamanho dos elementos.

E não se esqueça de comentar aqui abaixo, caso essa propriedade (ou a falta dela) já tenha te dado problemas.

Obrigado pela sua leitura, e até a próxima :)

💖 💪 🙅 🚩
demenezes
deMenezes

Posted on July 13, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related