Espaçamento

Podcast do CSS - 013: Espaçamento

Digamos que você tem uma coleção de três caixas empilhadas uma sobre a outra e quer espaço entre elas. Quantas maneiras de fazer isso no CSS?

Três caixas empilhadas com uma seta para baixo

A propriedade margin pode fornecer o que você precisa, mas também pode adicionar espaçamento adicional que você não quer. Por exemplo, como segmentar apenas o espaço entre cada um desses elementos? Um gap pode ser mais apropriado nesse caso. Há muitas maneiras de ajustar o espaçamento em uma interface, cada uma com pontos fortes e ressalvas próprias.

Espaçamento HTML

O próprio HTML fornece alguns métodos para espaçar elementos. Os elementos <br> e <hr> permitem espaçar elementos na direção do bloco, que, se você estiver em um idioma latino, é de cima para baixo.

Se você usar um elemento <br>, ele vai criar uma quebra de linha, como se você pressionasse a tecla Enter em um processador de texto.

O <hr> cria uma linha horizontal com espaço em um dos lados, conhecida como margin.

Além de usar elementos HTML, as entidades HTML podem criar espaço. Uma entidade HTML é uma string reservada de caracteres que são substituídas por entidades de caracteres pelo navegador. Por exemplo, se você digitar &copy; no arquivo HTML, ele será convertido em um caractere ©. A entidade &nbsp; é convertida em um caractere de espaço sem quebra, que fornece um espaço inline. Porém, tenha cuidado, porque o aspecto não quebrado desse personagem une os dois elementos, o que pode resultar em um comportamento estranho.

Margem

Para adicionar espaço fora de um elemento, use a propriedade margin. A margem é como adicionar algo ao redor do seu elemento. A propriedade margin é a abreviação de margin-top, margin-right, margin-bottom e margin-left.

Um diagrama das quatro principais áreas do modelo de box.

A abreviação margin aplica propriedades em uma ordem específica: superior, direita, inferior e esquerda. Você pode se lembrar delas com problemas: TRouBLe.

A palavra &quot;Problem&quot; para baixo com T, R, B e L,
se estendendo para cima, direita, baixo e esquerda.
Uma caixa com setas mostrando as rotas.

A abreviação margin também pode ser usada com um, dois ou três valores. Adicionar um quarto valor permite definir cada lado individual. Eles são aplicados da seguinte forma:

  • Um valor será aplicado a todos os lados. (margin: 20px).
  • Dois valores: o primeiro valor será aplicado aos lados superior e inferior e o segundo valor será aplicado aos lados esquerdo e direito. (margin: 20px 40px)
  • Três valores: o primeiro valor é top, o segundo é left e right e o terceiro é bottom. (margin: 20px 40px 30px).

A margem pode ser definida com um comprimento, porcentagem ou valor automático, como 1em ou 20%. Se você usar uma porcentagem, o valor será calculado com base na largura do bloco que o contém.

Isso significa que, se o bloco que o contém tiver uma largura de 250px e o elemento tiver um valor de margin de 20%: cada lado do elemento terá uma margem calculada de 50px.

Também é possível usar um valor de auto para a margem. Para elementos no nível do bloco com um tamanho restrito, uma margem auto ocupará o espaço disponível na direção em que é aplicada. Um bom exemplo é este, do módulo flexbox, em que os itens se afastam uns dos outros.

Outro bom exemplo de margem auto é um wrapper centrado horizontalmente com uma largura máxima. Esse tipo de wrapper é frequentemente usado para criar uma coluna central consistente em um site.

.wrapper {
    max-width: 400px;
    margin: 0 auto;
}

Aqui, a margem é removida dos lados superior e inferior (bloco), e auto compartilha o espaço entre os lados esquerdo e direito (in-line).

Margem negativa

Valores negativos também podem ser usados para margem. Em vez de adicionar espaço entre elementos irmãos adjacentes, ele reduz o espaço entre eles. Isso poderá resultar em elementos sobrepostos, se você declarar um valor negativo que é maior do que o espaço disponível.

Recolhimento da margem

O colapso da margem é um conceito complicado, mas é algo que você encontrará com frequência ao criar interfaces. Digamos que você tenha dois elementos: um título e um parágrafo com margem vertical:

<article>
  <h1>My heading with teal margin</h1>
  <p>A paragraph of text that has blue margin on it, following the heading with margin.</p>
</article>
h1 {
    margin-bottom: 2rem;
}

p {
    margin-top: 3rem;
}

À primeira vista, você não saberia que o parágrafo seria espaçado 5em a partir do título, porque 2rem e 3rem juntos são calculados como 5rem. No entanto, como a margem vertical é recolhida, o espaço é, na verdade, 3rem.

O recolhimento da margem seleciona o maior valor de dois elementos adjacentes com a margem vertical definida nos lados adjacentes. A parte de baixo do h1 encontra a parte de cima da p, de modo que o maior valor da margem de baixo do h1 e a margem de cima da p são selecionados. Se a h1 tivesse 3.5rem de margem inferior, o espaço entre as duas seria 3.5rem, porque é maior que 3rem. Somente as margens do bloco são recolhidas, não as margens inline (horizontais).

O recolhimento da margem também ajuda com elementos vazios. Se você tiver um parágrafo com uma margem superior e inferior de 20px, ele só criará 20px de espaço, não 40px. No entanto, se algo for adicionado ao interior desse elemento, incluindo padding, a margem não será mais recolhida por si só e será tratada como qualquer caixa com conteúdo.

Teste seu conhecimento

Teste seus conhecimentos sobre o recolhimento de margem

Se dois elementos empilhados um sobre o outro tiverem 20 px de margem superior e 30 px de margem inferior, quanto espaço haverá entre eles?

10px
Tente de novo.
20px
Resposta incorreta.
30px
O CSS ocupará o maior espaço de margem entre os elementos. Isso!
40px
Tente de novo.

Como impedir o recolhimento da margem

Se você fizer um elemento posicionado de forma absoluta, usando position: absolute, a margem não será mais recolhida. A margem também não será recolhida se você usar a propriedade float.

Se você tiver um elemento sem margem entre dois elementos com margem do bloco, a margem também não será recolhida, porque os dois elementos com margem do bloco não são mais irmãos adjacentes: eles são apenas irmãos.

Na lição sobre layout, você aprendeu que os contêineres flexbox e de grade são muito parecidos com os contêineres em bloco, mas lidam com os elementos filhos de forma muito diferente. Esse também é o caso do recolhimento da margem.

Se usarmos o exemplo original da lição e aplicarmos o flexbox com direção da coluna, as margens serão combinadas, em vez de recolhidas. Isso pode fornecer previsibilidade com o trabalho de layout, para que os contêineres flexbox e grid são projetados.

O recolhimento da margem e da margem pode ser complicado de entender, mas entender como eles funcionam, em detalhes, é muito útil, por isso esta explicação detalhada é altamente recomendada.

Padding

Em vez de criar espaço fora da caixa, como o margin faz, a propriedade padding cria espaço dentro da caixa, como isolamento.

Caixa com setas apontando para dentro, mostrando que o padding está dentro dela.

Dependendo do modelo de caixa que você está usando, abordado na lição de modelo de caixa, padding também pode afetar as dimensões gerais do elemento.

A propriedade padding é a abreviação de padding-top, padding-right, padding-bottom e padding-left. Assim como margin, padding também tem propriedades lógicas: padding-block-start, padding-inline-end, padding-block-end e padding-inline-start.

Posicionamento

Também abordado no módulo layout, se você definir um valor para position diferente de static, poderá espaçar os elementos com as propriedades top, right, bottom e left. Há algumas diferenças no comportamento desses valores direcionais:

  • Um elemento com position: relative vai continuar no fluxo do documento, mesmo quando você definir esses valores. Eles também serão relativos à posição do elemento.
  • Um elemento com position: absolute vai basear os valores direcionais da posição do elemento pai relativo.
  • Um elemento com position: fixed baseia os valores direcionais na janela de visualização.
  • Um elemento com position: sticky só vai aplicar os valores direcionais quando estiver no estado ancorado/travado.

No módulo de propriedades lógicas, você vai aprender sobre as propriedades inset-block e inset-inline, que permitem definir valores direcionais que respeitam o modo de gravação.

As duas propriedades são abreviações que combinam os valores start e end. Dessa forma, elas aceitam um valor a ser definido para start e end ou dois valores individuais.

Grade e flexbox

Por fim, tanto na grade quanto no flexbox, é possível usar a propriedade gap para criar espaço entre elementos filhos. A propriedade gap é a abreviação de row-gap e column-gap. Ela aceita um ou dois valores, que podem ser comprimentos ou porcentagens. Você também pode usar palavras-chave como unset, initial e inherit. Se você definir apenas um valor, o mesmo gap será aplicado às linhas e colunas, mas se você definir os dois valores, o primeiro será row-gap e o segundo será column-gap.

Com o flexbox e a grade, você também pode criar espaço usando os recursos de distribuição e alinhamento, que abordamos no módulo de grade e no módulo flexbox.

Representação em diagrama de uma grade com lacunas

Como criar espaçamento consistente

É uma boa ideia escolher uma estratégia e mantê-la para ajudar a criar uma interface de usuário consistente, com bom fluxo e ritmo. Uma boa maneira de fazer isso é usar medidas consistentes para o espaçamento.

Por exemplo, você pode se comprometer a usar 20px como uma medida consistente para todas as lacunas entre elementos, conhecidas como gutters, para que todos os layouts pareçam consistentes. Você também pode usar 1em como o espaçamento vertical entre o conteúdo do fluxo, o que alcança um espaçamento consistente com base no font-size do elemento. Independentemente da sua escolha, salve esses valores como variáveis (ou propriedades personalizadas de CSS) para tokenizar esses valores e facilitar um pouco a consistência.

Espaçamento consistente entre elementos,
usando 20 px para um layout ou 1 em para conteúdo de fluxo.

:root {
  --gutter: 20px;
  --spacing: 1em;
}

h1 {
  margin-left: var(--gutter);
  margin-top: var(--spacing);
}

Com essas propriedades, você pode defini-las uma vez e usá-las em todo o CSS. Quando eles são atualizados, seja localmente em um elemento ou globalmente, os valores são transmitidos pela cascata e os valores atualizados são refletidos.

Teste seu conhecimento

Teste seus conhecimentos sobre espaçamento

É seguro usar HTML para espaçamento quando...

É apenas um.
Tente de novo.
Ninguém vai perceber.
Tente de novo.
É só para o espaço.
Tente de novo.
Ele ajuda na compreensão do documento.
Você acertou!

Para criar espaço dentro de uma caixa, use...

Margem
A margem é para empurrar para fora da caixa.
HTML
Elas servem para espaçamento e divisão de conteúdo.
Gap
A lacuna serve para espaçamento entre as caixas.
Padding
O padding serve para criar espaço dentro de uma caixa.

Para criar um espaço fora de uma caixa, use...

Margem
A margem é para empurrar para fora da caixa.
HTML
Elas servem para espaçamento e divisão de conteúdo.
Gap
A lacuna serve para espaçamento entre as caixas.
Padding
O padding serve para criar espaço dentro de uma caixa.

Para criar espaço entre caixas, use...

Margem
A margem é para empurrar para fora da caixa.
HTML
Elas servem para espaçamento e divisão de conteúdo.
Gap
A lacuna serve para espaçamento entre as caixas.
Padding
O padding serve para criar espaço dentro de uma caixa.