Fork me on GitHub

Getting Started

Um guia para iniciantes na área de web.

Box Model

Entendendo como funciona elementos no HTML

Sempre quando vamos estilizar algum elemento via CSS, é comum, e precisamos estar cientes, que alguma alteração que iremos fazer possa impactar em outros elementos. Isso fica fácil de compreender quando entendemos o conceito de box model.

Basicamente, a idéia do box model é composta por quatro partes:

Resumindo, podemos dizer que o box model trata-se de como as 4 propriedades acima se relacionam para compor a dimensão do elemento.

Imagem demonstrando o conceito de box-model
.classe {
    width: 50px;
    height: 50px;
    border: 1px solid gray;
    padding: 10px 20px;
}

Se aplicarmos a classe acima em um elemento, ele vai ter as dimensões que setamos (50 pixels de altura e largura), certo? Errado. O elemento vai ser renderizado com 72 pixels de altura e 92 pixels de largura. Isso acontece devido ao fato das propriedades padding e border serem somadas à largura e altura já definidas, aumentando as dimensões do elemento. Isso nos leva a ver que as propriedades width e height definem as dimensões do seu conteúdo e não do elemento como um todo.

Largura

50 (largura definida) +
20 (padding left) +
20 (padding right) +
1 (border left) +
1 (border right) => 92 pixels de largura

Altura

50 (altura definida) +
10 (padding top) +
10 (padding bottom) +
1 (border top) +
1 (border bottom) => 72 pixels de altura

Um exemplo prático pra vermos a dor de cabeça que você pode ter no seu dia a dia. Imagine que você precise ter um elemento que ocupe 100% da largura disponível. Mas também precisa que esse elemento tenha 10 pixels de padding e uma borda de 1 pixel.

.dor-de-cabeca {
    width: 100%;
    padding: 10px;
    border: solid 1px gray;
}

Seu elemento com a classe dor-de-cabeca ultrapassa o limite de 100% que você tinha definido, provavelmente quebrando o layout. A nova largura dele é resultante da soma: 100% (largura definida) + 20 pixels (padding left e right) + 2 pixels (border left e right).

A propriedade box-sizing

Já vimos o tanto de facilidades que o CSS3 trouxe para a vida dos desenvolvedores. Uma delas é a propriedade box-sizing que permite que mudemos o comportamento do box-model.

Por padrão, todos os elementos possuem o valor content-box para essa propriedade. Trata-se do que vimos nos exemplos acima: o box-model é definido apenas pelo conteúdo.

box-sizing: content-box;

Um outro exemplo para exemplificar o box-model com o uso do content-box. Considere os elementos, abaixo:

.elemento1 {
    background: #ddd;
    width: 250px;
    height: 50px;
}

.elemento2 {
    background: #ddd;
    width: 250px;
    height: 50px;
    padding: 0 50px;
}
Imagem demonstrando o valor content-box para a propriedade box-sizing e as diferenças no cálculo da largura de elementos

Os elementos são definidos com a mesma largura, mas como podemos ver na imagem acima, o elemento2 é renderizado maior devido ao padding.

A solução border-box

A propriedade box-sizing permite um novo valor que resolve todos os problemas apresentados nos exemplos anteriores:

    box-sizing: border-box;

O que ela faz? Simples. Ela altera o comportamento do box-model, fazendo com que o navegador calcule a largura/altura do elemento contando não apenas o seu conteúdo (como visto no content-box), mas também considerando o padding (espaçamento) e border (borda) do elemento.

O exemplo anterior, com a aplicação do border-box:

.elemento1,
.elemento2 { box-sizing: border-box; }

.elemento1 {
    background: #ddd;
    width: 250px;
    height: 50px;
}

.elemento2 {
    background: #ddd;
    width: 250px;
    height: 50px;
    padding: 0 50px;
}
Imagem demonstrando o valor border-box para a propriedade box-sizing e o novo comportamento do box-model para o cálculo da largura de um elemento

Suporte

O suporte atual é bem grande, com mais de 90% (em torno de 77% com suporte parcial e 15% com suporte total), o que nos leva a utilizar os prefixos sempre que formos utilizar a propriedade.

* {
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
        -ms-box-sizing: border-box;
            box-sizing: border-box;
}