Shortcut
As margens que se encostam, sem nada entre elas, se juntam em uma só e ocupam o mesmo espaço na tela.
Veja o conteúdo abaixo:
<p>Primeiro texto</p>
<p>Segundo texto</p>
p {
margin-top: 10px;
margin-bottom: 10px;
}
E agora responda: quantos pixels de espaçamento existem entre o primeiro e o segundo parágrafo:
0px
10px
20px
Girafa
Se você respondeu 0px, largue as drogas.
Se respondeu 10px, já sabe do que vou falar. O que está fazendo aqui? Brincadeira, fica, vai ter bolo.
Se respondeu 20px, esse post é para você.
Agora, se respondeu girafa... tá tudo bem?
Assim como falei nesse post sobre box model, HTML é um monte de caixinhaa dentro de caixinha. Os componentes que formam elas são:
Conteúdo
Padding
Border
Margin
Se quiser entender melhor, revise alguns conceitos no post antes de prosseguir.
Agora vou falar sobre:
O que é o margin collapsing
As 3 situações onde ele acontece
Margin collapsing com mais de duas margens
Cálculo
Como corrigir
Agora que o box model está mais claro para você, eu começo com a definição da palavra.
O que é margin collapsing?
Antes de tudo, o que é margin?
Margin é uma das propriedades CSS que compõem o box model. O seu valor cria um espaçamento para os elementos próximos nas quatro direções: cima, direita, baixo, esquerda (parece golpe do Street Fighter).
Seu objetivo é criar um espaço entre ele e um elemento irmão. Margin não serve (ou não deveria servir) para separar um elemento filho de um pai.
Em alguns momentos, você vai encontrar algumas margens que se encostam, sem nada entre elas. Elas podem ser do mesmo elemento ou de elementos diferentes. Nesse momento, acontece o margin collapsing, que é quando as duas margens se sobrepõem e ocupam o mesmo espaço na tela.
É importante deixar claro que isso só acontece com margin-top
e margin-bottom
, e nunca com margin-left
e margin-right
.
Mas o margin collapsing não acontece sempre.
Quando o margin collapsing acontece
O margin collapsing acontece em 3 situações.
1. Elementos irmãos próximos
É o caso mais clássico.
Quando dois elementos irmãos são posicionados verticalmente, o margin-bottom
do primeiro se junta com o margin-top
do segundo.
2. Elemento pai com primeiro e último filho
Briga de família aqui.
O margin collapsing acontece entre o margin-top
do elemento pai e o margin-top
do primeiro filho:
E entre o margin-bottom
do elemento pai com o margin-bottom
do último filho:
Perceba que nesse caso, o collapsing acontece entre duas margens no mesmo sentido: para cima ou para baixo.
Caso a margem que se destaque seja do elemento filho (por exemplo, o segundo parágrafo), ela é "virtualmente" transferida ao pai (div-1
). Assim, ele cria um espaço para seus irmãos (outras divs irmãs da div-1
). Mas se olhar pelo devtools, ela permanece no filho.
3. Elemento vazio
Entende-se um elemento vazio como sem valor, logo ele praticamente some da tela.
Se um elemento HTML estiver vazio, o margin-top
e margin-bottom
dele se colapsam.
Perceba que é como se o terceiro parágrafo ignorasse a existência do segundo parágrafo, o vazio.
Entender as 3 situações onde o margin collapsing acontece, não é muito complicado. Porém agora você verá outros detalhes sobre esse fenômeno.
Margin collapsing com mais de duas margens
Preciso dizer que eu menti.
Você lembra que eu disse "o margin collapsing é quando duas margens se sobrepõem"? Não era bem verdade, pois mais de duas margens podem estar envolvidas em um collapsing.
Para isso, é necessário combinar 2 dos 3 casos que expliquei (ou todos eles):
<div class="div-1">
<p>Texto</p>
</div>
<div class="div-2">
<p>Texto</p>
</div>
.div-1 {
margin-bottom: 5px;
}
.div-1 p {
margin-bottom: 15px;
}
.div-2 {
margin-top: 20px;
}
.div-2 p {
margin-top: 10px;
}
Todas as margens que declarei acima, se sobrepõem, basta testar o código para confirmar.
E após toda essa salada de margins, é possível ver que o espaço final foi de 20px, exatamente o margin-top
da div-2
.
Mas como isso foi definido?
Como calcular o valor final de um margin collapsing
Quando duas ou mais margens se sobrepõem, o navegador calcula a margem final.
Apesar de saber que ele fará esse trabalho para você, é importante entender como esse cálculo é feito. Assim, você começa a se aprofundar nos conceitos de como o navegador e a web funcionam.
Margens positivas
Foi o caso do exemplo anterior.
Se duas ou mais margens positivas estiverem em um collapsing, o resultado final será a maior margem:
Margins envolvidas no collapsing | Margin final |
---|---|
5px | 35px |
35px | |
20px |
Margem positiva com outra zerada
Nesse caso, segue a mesma regra anterior: permanece a maior margem, ou a única margem positiva:
Margins envolvidas no collapsing | Margin final |
---|---|
5px | 18px |
18px | |
0 |
Margens negativas
Se apenas margens negativas estiverem envolvidas, o resultado final será a menor margem:
Margins envolvidas no collapsing | Margin final |
---|---|
-5px | -20px |
-20px | |
-15px |
Margin negativa com positiva
Quando houver margens de sinais diferentes, basta somar os extremos: a maior com a menor.
Se houver apenas duas margens, some elas.
Se houver mais de duas, ignore as margens com valores intermediários no cálculo.
Margins envolvidas no collapsing | Cálculo | Margin final |
---|---|---|
35px | 35px + (-15px) | 20px |
5px | ||
-10px | ||
-15px |
E agora finalmente, como se livrar desse incômodo.
Como corrigir o margin collapsing?
Você se lembra do capítulo Quando o margin collapsing acontece? Agora você verá como corrigi-lo, ou Quando o margin collapsing não acontece.
Para isso, basta apenas quebrar uma das exigências do margin collapsing. Existem muitas formas de fazer isso. Veja algumas:
Use float
Obs: não use mais float :) flexbox e grid estão aí para isso.
Mas se usar, saiba que não haverá margin collapsing em elementos flutuantes.
Resolve os seguintes casos:
Elementos irmãos próximos
Elemento pai com primeiro e último filho
Elemento vazio
Use position
Um elemento posicionado não irá causar margin collapsing.
Isso vale tanto para position: absolute
, quanto para position: fixed
.
Resolve os seguintes casos:
Elementos irmãos próximos
Elemento pai com primeiro e último filho
Elemento vazio
Use padding
No começo do post, eu disse que o collapsing acontece quando duas margens se encostam. Logo, se as margens não se encostam, não acontece o collapsing.
A forma mais simples de fazer isso é adicionar um padding em um dos elementos.
Resolve os seguintes casos:
Elemento pai com primeiro e último filho
Elemento vazio
Use border
A borda é outro componente do box model que, ao ser inserida, impede o margin collapsing.
Resolve os seguintes casos:
Elemento pai com primeiro e último filho
Elemento vazio
Use propriedades de altura
Essas propriedades de altura evitam o margin collapsing:
height
min-height
max-height
line-height
A regra diz que as margens precisam se tocar para acontecer o collapsing. Logo, definir uma altura é o suficiente para separá-las.
Resolve os seguintes casos:
Elemento pai com primeiro e último filho
Elemento vazio
Use overflow
Se o elemento pai tiver uma barra de rolagem em função da propriedade overflow
, não haverá margin collapsing. Isso acontece tanto com overflow: scroll
, quanto com overflow: auto
.
É importante que esse elemento também não seja vazio.
Resolve os seguintes casos:
Elemento pai com primeiro e último filho
Insira um conteúdo entre as bordas
O margin collapsing não acontece caso haja qualquer conteúdo entre as duas (ou mais) margens.
Esse conteúdo pode ser até a tag <br />
. Mas venhamos e convenhamos, você não vai fazer isso né?
Resolve os seguintes casos:
Elemento pai com primeiro e último filho
Elemento vazio
Use flexbox ou grid
A maravilha do CSS moderno.
Se você colocar display: flex / grid
em um elemento, não irá acontecer o margin collapsing entre seus filhos.
Resolve os seguintes casos:
Elementos irmãos próximos
Some a isso, o fato de você poder separar elementos dentro de flexbox e grid com a propriedade gap do CSS . A maioria dos navegadores modernos já suporta essa propriedade, segundo o Can I Use . Assim, nem é preciso usar margin
.
Callback
Margin collapsing é quando o margin-top
/margin-bottom
de um elemento se junta com o de outro ou do mesmo elemento.
Acontece entre:
Elementos irmãos próximos
Elemento pai com primeiro e último filho
E elementos vazios
Pode acontecer com mais de duas margens ao mesmo tempo.
Dependendo do valor das margens envolvidas, o valor final pode variar bastante em função do cálculo.
Existem também diversas formas de corrigir o margin collapsing, e cada uma se aplica a uma situação diferente.
O que achou? Diferente de mim, você encontra muito margin collapsing no seu dia a dia?
Comente aqui aqui embaixo!
Muito obrigado pela sua leitura 🙂
Continue estudando:
https://developer.mozilla.org/pt-BR/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
https://blog.cisne.dev/desmistificando-o-margin-collapsing-do-css/
https://www.freecodecamp.org/news/what-is-margin-collapse-and-how-to-avoid-it/
https://css-tricks.com/what-you-should-know-about-collapsing-margins/