CSS tiene mala reputación por no comportarse como la gente espera. Una de las cosas que más desconcierta a la gente son los márgenes. Parecen tan simples, pero tienen el potencial de causar algunos problemas realmente extraños.
Para las personas que recién comienzan a usar CSS, es fácilmente una de esas cosas que pueden hacerte pensar "¡este es un lenguaje estúpido que no tiene sentido!"
Lo veo todos los días, tanto en el aula cuando la gente trata de resolver sus problemas de espaciado como también en las secciones de comentarios de YouTube.
En cierto modo, los márgenes son un microcosmos de CSS en general. CSS parece tan simple con sus property: value
pares, pero a medida que avanza con él, se da cuenta de que están sucediendo muchas cosas.
Los márgenes también parecen tan simples. Agregue un margen y agregue un espacio vacío alrededor de ese elemento. Pero luego, de repente, se comportan de manera un poco diferente en una situación que en otra, o agrega algo margin-top
a un elemento secundario y, en cambio, es el elemento primario el que se mueve hacia abajo.
Sobreviene la frustración.
En este artículo, espero arrojar algo de luz sobre cómo funcionan los márgenes. Veremos algunos de los problemas comunes que ocurren, así como soluciones simples a esos problemas.
Para repasar todo esto, usaré ejemplos de mi Bootcamp de diseño web receptivo en Scrimba, del cual saqué este diseño simple:

¿Qué son los márgenes de todos modos?
Antes de que realmente saltemos al extremo profundo aquí, ¡quiero asegurarme de que todos sepamos qué son realmente los márgenes!
Voy a suponer que todos sabemos que los márgenes son parte del modelo de caja, con el margen en todo el exterior, después del contenido en sí, el relleno y el borde.
El MDN los explica muy bien (énfasis mío):
El margen es la capa más externa, que envuelve el contenido, el relleno y el borde como un espacio en blanco entre este cuadro y otros elementos . Su tamaño se puede controlar mediante el margen y las propiedades relacionadas.En otras palabras, es efectivamente un espacio vacío que podemos usar para crear espacio entre un cuadro y otro en nuestro diseño.
Manejo de hojas de estilo de agente de usuario
Los navegadores vienen con una sorprendente cantidad de CSS por defecto, que llamamos hojas de estilo de agente de usuario . Estos estilos son la razón por la que, sin CSS de nuestra parte, un
es más grande que un
y por qué
tiene un margen que solemos eliminar siempre.
Estos estilos son importantes, ¡pero también conducen a uno de los mayores problemas con los que se encuentran las personas con los márgenes! Los márgenes no están predeterminados 0
en todos nuestros elementos, y esto puede causar todo tipo de problemas extraños que exploraremos en breve.
Las listas, las citas en bloque, los párrafos y los encabezados tienen todos margin
ellos (entre otros elementos). Si bien a veces son solo un pequeño inconveniente, el margen predeterminado en los párrafos y encabezados parece ser el que causa la mayoría de los problemas.
De forma predeterminada, los márgenes izquierdo y derecho de un elemento de texto están configurados en 0
, pero todos vienen con margin-top
y margin-bottom
.
A menudo le digo a la gente que esos valores predeterminados superiores e inferiores son aproximadamente los mismos que los font-size
de ese elemento, ya que es cierto para
tanto como
mediante
. por
es en realidad 0.67em
y para
es 0.83em
.
Esto significa que existe espacio entre los elementos de nuestra página incluso si no hemos establecido un margen explícitamente.
Volveremos a estos valores predeterminados en un segundo.
Márgenes colapsados
Los márgenes que se derrumban son donde a menudo comienzan los dolores de cabeza.
Cuando dos elementos tienen márgenes verticales que se tocan entre sí, se fusionan efectivamente entre sí.
Ya es un comportamiento extraño, y luego lo agrego al hecho de que es solo para los márgenes verticales (superior e inferior), entiendo por qué la gente se confunde y se molesta con ellos.
Podemos ver esto en acción con el siguiente ejemplo:
p { font-size: 18px; margin-bottom: 40px; } .links { margin-top: 40px; }
Para ayudar a ilustrar lo que está sucediendo aquí, la .links
clase está en el último párrafo (
When people do something like this, they expect the margin between the middle paragraph and the links below it to be 80px (
40px
+ 40px
), but in reality, it's 40px. The two margins are touching each other, so they merge into one another.

To push it even more, let's give our
s' a margin-bottom
to 100px
:
p { font-size: 18px; margin-bottom: 100px; } .links { margin-top: 40px; }
Again, the two margins don't add together, they collapse into one another, so the total space here is 100px
.

This is a good thing
In cases like this, it's actually a good thing, though. If there are several elements with different margins, there is no need to add the margins together to see how large the gap between the elements is because we can rely on the fact that the larger margin always wins.
We often don't even think about it, it just works the way we expect it to work.
When it's not a good thing
That said, one instance where margin collapse causes all sorts of confusion is when the first child within an element has a margin-top
that merges with the parent's margin-top
.
Let's look at that same screenshot again:

There is a white space between the top of the viewport and the black box. That's not from the body (it's much bigger than the 8px
margin the body would have).
Care to guess where it's coming from?
It's actually coming from the
at the top of that black box.
Remember when I mentioned that the user-agent stylehsheets can do some odd things?
To help explain exactly what's happening here, let's add a much bigger margin-top
to the h1
.
.card { background: #000; color: white; width: 560px; margin: 0 auto; } h1 { font-size: 24px; margin-top: 100px; } p { font-size: 18px; margin-bottom: 100px; } .links { margin-top: 10px; }
I see people do this all the time, trying to push the title down within its parent. However, rather than working as expected, we get a giant space on top of the entire card!

This is because the margin-top
on the
merges with the margin-top
on the parent element.
There is nothing separating the top of the child and the parent in this case. So when we add margin-top
to the child, it touches the parent's margin-top
. And, as we saw above, when two margins touch one another, they merge into a single margin.
So while we are giving the margin to the child, it's being applied to the parent.
This is why people hate CSS.
Similarly, in the code above we gave all paragraphs a margin-bottom
. That margin on the p.link
elements touches the margin-bottom
of the .card
element, which means that the two merge together and the margin affects the .card
element instead of the links.

Although this isn't causing an issue for the site we are currently creating, it could cause problems if we later decided to add further elements to the page.
The problem is, we're using margin
for the wrong purpose
If I want space between the top of the .card
element and the children inside it, I shouldn't be using margin
anyway.
Beginners often get mixed up between margin
and padding
. My general rule of thumb is if you want empty space, use margin
. If you want more background, use padding
.
In this case, we want our .card
to have more background, so we shouldn't be adding a margin
to its children. Instead we should add padding
to that element itself.

In the image above, we can see the padding and the margin. The
on top still has a margin, but it's no longer merging with the .card
because the padding
has added in a buffer. This prevents the .card
's and h1
margin from touching one another.
As the padding adds sufficient space between the
s and the
s, we can now remove the margins we previously added to them.

Margins don't always collapse
There are some exceptions to collapsing margins. The direct descendants of grid and flex parents do not have collapsing margins.
Cue the ?.
But there is a bit of a workaround for this as well, which brings us full circle back to those user agent-stylesheets we talked about at the start.
There is an easy way to avoid even thinking about collapsing margins
First off, there is my general rule of thumb that I talked about above:
- If you need empty space, use
margin
- If you need more background, use
padding
That will get you out of trouble most of the time. But let's add an extra rule to this that will help even more:
- Try to avoid
margin-top
except when you really need it
This rule is in a bit of conflict with the user-agent-styles, which set a margin-top
and margin-bottom
to a bunch of elements, which is one reason I often will do something like this:
h1, h2, h3, h4, h5, h6, p, ul, ol { margin: 0 0 1em 0; }
It eliminates a lot of the issues that come from collapsing margins on their own, as well as differences in your layout when some places are using flex or grid and others are not.
(Note: if you inspect the code here on freeCodeCamp, you'll see they do something similar as well!)
It's not a perfect solution, and I often do use a little margin-top
on certain subtitles or in specific situations where it's called for. But I'm doing it very intentionally instead of letting the user-agent-styles potentially get in the way in some unforeseen way.
These lessons are just a snippet of my much larger course on responsive web design. To continue this coding journey, take a look at the course.
In the course I cover an introduction to responsive web design, and dive into both flexbox and grid, all the while trying to show people how much fun CSS really is once you start to understand how it works.
Happy coding :)