Una de las primeras cosas que muchos de nosotros aprendimos cuando aprendimos CSS fueron las características de los diversos elementos de un bloque en CSS, descritos como el "Modelo de bloque CSS". Uno de los elementos en el modelo de bloque es el margen (margen exterior), un área transparente alrededor del bloque que repele a otros elementos del contenido de este bloque. Las propiedades de
margin-top
,
margin-right
,
margin-bottom
y
margin-left
se describieron ya en CSS1, junto con la propiedad de margen abreviado para la configuración simultánea en las cuatro propiedades.
El margen parece bastante sencillo, sin embargo, en este artículo veremos algunos puntos con los que las personas tropiezan cuando lo usan. En particular, cómo interactúan los márgenes entre sí y cómo funciona realmente el colapso de los márgenes externos.
Modelo de bloque CSS
Al igual que con todos los artículos sobre los componentes del Modelo de bloque CSS CSS, debemos determinar qué queremos decir con esto y cómo se clasificó el modelo en diferentes versiones de CSS. El modelo de bloque se refiere a cómo los diversos componentes del bloque (contenido (pad), relleno (relleno), borde (marco) y margen (relleno) se ubican e interactúan entre sí. En CSS1, el modelo de bloque se representó usando el diagrama ASCII que se muestra en la imagen a continuación.

Las cuatro propiedades para cada lado del bloque y la propiedad de margen abreviado se definieron en CSS1.
La especificación CSS2.1 tiene una ilustración para demostrar el modelo de bloque y también define los términos que seguimos utilizando para describir diferentes bloques. La especificación describe el cuadro de contenido, el cuadro de relleno, el cuadro de borde y el cuadro de margen, cada uno de los cuales está definido por los bordes de contenido, relleno, borde y margen, respectivamente.

Actualmente hay una especificación para la versión
Block Model 3 como borrador de trabajo. Al definir el modelo de bloque y los
márgenes , nos devuelve a CSS2, por lo que a lo largo del artículo usaremos la definición de CSS2.
Margen de colapso
La especificación CSS1 definió no solo los márgenes, sino también su colapso. Este comportamiento se ha convertido en una fuente de muchas decepciones. El margen de contracción tiene sentido cuando considera que en aquellos días, CSS se usaba como un lenguaje de marcado para documentos de texto. El margen de contracción significa que cuando un encabezado con un margen inferior es seguido por un párrafo que tiene un margen superior, estos dos guiones no se suman, creando una gran brecha entre los elementos.
Cuando dos márgenes colapsan, el espacio entre los elementos se vuelve igual al mayor de los dos guiones. La sangría más pequeña en realidad termina dentro de la más grande
Colapso del margen en las siguientes situaciones:
- Hermanos adyacentes (monoparental)
- Bloques vacíos
- Padre y primer / último hijo
Elementos de enfermería adyacentes
Comenzaré la descripción con una demostración de cómo colapsan los márgenes entre hermanos adyacentes. Excepto como se indica a continuación, si tiene dos elementos mostrados uno tras otro en la secuencia normal, el margen inferior del primer elemento colapsará con el margen superior del elemento posterior.
En el ejemplo de CodePen a continuación, hay tres elementos
div
. Para el primer elemento, el margen superior e inferior son 50 px, para el segundo - 20 px, para el tercero - 3em. El margen entre los dos primeros elementos es de 50 px, ya que el margen inferior del elemento inferior es absorbido por el margen superior del elemento superior. El margen entre los dos segundos elementos es 3em, ya que 3em es mayor que 20 píxeles en el margen inferior del segundo elemento.
Bloques vacíos
Si el bloque está vacío, sus márgenes superior e inferior pueden colapsarse entre sí. En el siguiente ejemplo de CodePen, el segundo elemento con la clase
empty
(no visible, porque está vacío) tiene un margen superior e inferior de 50 píxeles, sin embargo, el espacio entre el primer y el tercer elemento no es de 100 píxeles, sino de 50. Esto es el resultado del colapso de dos márgenes.
Agregar algo al bloque (incluso relleno) hará que los márgenes superior e inferior se usen, no se contraigan.
Padre y primer / último hijo
Este escenario de colapso del margen desconcierta a las personas con más frecuencia que otros, ya que no es intuitivo. En el próximo CodePen, tenemos un
div
con la clase
wrapper
(wrapper), y configuro este
div
propiedad de
outline
del rojo, para que se puedan ver sus bordes. Los tres niños tienen un margen de 50 píxeles. Sin embargo, el primer y el último elemento son adyacentes a los bordes del elemento envoltorio; No hay sangría de 50 píxeles entre el elemento y el contenedor.
Esto se debe a que el margen del elemento secundario se contrae con cualquier margen del elemento primario de tal manera que termine fuera del elemento primario. Puede ver esto si prueba al niño usando el panel del navegador del desarrollador. El área resaltada en amarillo es margen.

Contraer solo margen
El último ejemplo también destaca algo sobre el margen de colapso. En CSS2, solo los márgenes verticales (superior e inferior) fueron diseñados para colapsar. Por lo tanto, en el ejemplo anterior, los márgenes a la izquierda y a la derecha no se contraen y terminan dentro del envoltorio.
Nota: Vale la pena recordar que el margen se contrae solo en la dirección del bloque, por ejemplo, entre párrafos.
Prevención de colapso
El margen no se contrae si el elemento se establece en posicionamiento absoluto o la propiedad
float
. Sin embargo, si se encuentra en una situación en la que el margen colapsa, ¿cómo se puede evitar?
El margen de colapso no ocurre en una situación en la que hay algo intermedio.
Por ejemplo, los márgenes superior e inferior de un bloque vacío no colapsan si el bloque se establece en un borde o relleno. En el siguiente ejemplo, agregué un bloque de relleno de 1px. Ahora en la parte superior e inferior del bloque hay un margen de 50 px.
Esta es la lógica: si un bloque vacío no tiene borde ni relleno, se vuelve prácticamente invisible. Por ejemplo, podría ser un párrafo vacío colocado en el marcado de su CMS. Si su CMS agregó elementos de párrafo redundantes, probablemente no querrá que causen una sangría grande entre otros párrafos porque su margen se tiene en cuenta. Agregue algo al bloque y obtenga estas sangrías.
Se puede ver un comportamiento similar con el margen del primer o último hijo cuyo margen se extiende más allá del padre. Si agregamos un borde al padre, el margen del niño permanecerá adentro.
Y de nuevo, hay lógica en este comportamiento. Si tiene elementos de contenedor para fines semánticos que no se muestran visualmente, probablemente no desee que creen una sangría grande cuando se muestren. Esto fue más útil cuando la web era principalmente texto. Y este comportamiento es menos útil cuando usamos elementos de diseño.
Crear un "contexto de formato de bloque"
El nuevo "Contexto de formato de bloque" (BFC) evitará que los márgenes se caigan del elemento padre. Si volvemos a ver el ejemplo con el primer y el último elemento secundario cuyos márgenes quedan fuera de los límites del elemento contenedor y configuramos el contenedor para
display: flow-root
, creando así BFC, el margen de los elementos secundarios permanecerá adentro.
Para obtener más información acerca de
display: flow-root
, lea mi artículo "
Comprender el diseño CSS y el contexto de formato de bloque ". Cambiar el valor de la propiedad de
overflow
a
auto
tendrá el mismo efecto, ya que también crea un nuevo BFC, aunque puede conducir a barras de desplazamiento que no son necesarias en ciertos casos
Contenedores Flex y Grid
Los contenedores Flex y Grid establecen el contexto de formato Flex y Grid para los niños, por lo que tienen un comportamiento de diseño de bloque diferente. Una de estas diferencias es que los márgenes no colapsan:
Un contenedor flexible establece un nuevo contexto de formato flexible para el contenido. Esto es lo mismo que establecer un contexto de formato de bloque, excepto que se utiliza el marcado flexible en lugar del marcado de bloque. Por ejemplo, los flotadores no funcionan dentro de un contenedor flexible, y el margen de un contenedor flexible no se contrae con el margen de los elementos secundarios.
- Flexbox Nivel 1
Si tomamos el ejemplo anterior y lo envolvemos con un contenedor Flex, que indica la dirección del eje principal de la columna flex-direction: queda claro que ahora el margen de los hijos no va más allá del ajuste. Además, los márgenes entre los elementos flexibles adyacentes no se contraen, por lo que obtenemos una distancia de 100 píxeles entre los elementos flexibles, que es la suma de los márgenes superior e inferior, que son 50 px cada uno.
Estrategias de margen para su sitio web
Debido al colapso, una buena solución sería ofrecer una forma consistente de trabajar con margen en su sitio. Lo más simple que puede hacer es establecer una regla para establecer el margen solo en la parte superior o inferior de los elementos. En este caso, no debería encontrar problemas de colapso con demasiada frecuencia, ya que el lado en el que se establece el margen siempre estará adyacente al lado del otro elemento sin el margen.
Nota : Harry Roberts
tiene una excelente publicación que detalla las razones por las cuales establecer el margen en una sola dirección es una buena idea, y no solo por resolver los problemas de colapso.
Este enfoque no resuelve el problema del margen que se cae de los elementos secundarios más allá de los límites de los padres, que puede encontrar. Este problema en particular suele ser menos común y comprender por qué sucede esto puede ayudar a encontrar una solución. La solución ideal es configurar los componentes que requieren que se
display: flow-root
, y con un respaldo (respaldo) para navegadores más antiguos, puede usar el
overflow
para crear un BFC (contexto de formato de bloque); convertir a los padres en un contenedor flexible; o incluso configurar el relleno a 1px. Tenga en cuenta que puede usar la solicitud de soporte del navegador para propiedades para determinar si la propiedad
display: flow-root
es compatible para que solo los navegadores más antiguos obtengan una solución menos óptima.
Creo que en la mayoría de los casos, la clave es comprender por qué los márgenes colapsan (o no). Esto le permitirá determinar cómo lidiar con esto en cada caso. Cualquiera sea el método que elija, comparta esta información con su equipo. Muy a menudo, el colapso del margen es un poco misterioso, por lo que las formas de lidiar con él no siempre son obvias. Un comentario en su código puede ser apropiado; incluso puede incluir un enlace a este artículo y ayudar a compartir conocimientos sobre el margen de colapso.
Decidí que complementaría este artículo con algunos datos adicionales relacionados con el margen.
Margen de interés
Cuando usas porcentajes en CSS, deberían ser porcentajes de algo. El margen (así como el relleno) establecido como porcentaje siempre se calculará en relación con el ancho del elemento principal. Esto significa que cuando use porcentajes, siempre tendrá el mismo margen desde todos los lados alrededor del elemento.
En el ejemplo de CodePen a continuación, tengo un contenedor con un ancho de 200 px, dentro del cual hay un bloque que tiene un margen = 10%. Desde todos los lados, el margen es de 20 px, que es el 10% de 200 px.
Margen en un mundo dependiente del flujo
A lo largo de este artículo, hablamos sobre los márgenes verticales, sin embargo, el CSS moderno, por regla general, piensa en la ubicación de los elementos en relación con la secuencia más que en relación con los lados físicos. Por lo tanto, cuando hablamos de márgenes verticales, en realidad estamos hablando de márgenes en la dimensión de bloque. Estos márgenes pueden ser superiores o inferiores en modo de escritura horizontal, o derecha o izquierda en modo vertical.
Después de trabajar con direcciones lógicas relativas al flujo, se hace más fácil hablar sobre el principio y el final del bloque que sobre la parte superior e inferior. Para facilitar esto, se introdujo una especificación de propiedades y valores booleanos en CSS. Reemplaza las propiedades físicas con propiedades relacionadas con el flujo.
Si hablamos de margen, esto nos da las siguientes alternativas (si trabajamos con inglés o cualquier otro modo grabado horizontalmente con la dirección del texto de izquierda a derecha).
- margin-top = margin-block-start
- margin-right = margin-inline-end
- margin-bottom = margin-block-end
- margin-left = margin-inline-start
También tenemos dos nuevas propiedades abreviadas:
- bloqueo de margen
- margen en línea
En el siguiente ejemplo de CodePen, utilicé palabras clave relacionadas con la transmisión y luego cambié el modo de ortografía de bloque. Puede ver cómo los márgenes siguen la secuencia de texto, en lugar de estar vinculados a los lados físicos.
Puede leer más sobre propiedades y valores lógicos en
MDN o en mi artículo,
Entendiendo las propiedades y valores lógicos , en Smashing Magazine.
En conclusión
Ahora ya sabe lo que debe saber sobre el margen. Brevemente:
- El margen puede colapsar. Comprender cuándo sucede esto y cuándo no lo ayudará a resolver cualquier problema que puedan crear.
- Instalar el margen en una sola dirección resuelve muchos problemas asociados con ellos.
- Al igual que con cualquier situación de CSS, comparta las decisiones que tome con su equipo y comente su código
- Tener en cuenta las medidas de bloque y línea en lugar de los lados físicos, arriba, derecha, abajo e izquierda le ayudará, ya que la web se está moviendo para independizarse del modo de escritura