Desbordamiento y Colapso de margenes

Overflow

La propiedad CSS overflow especifica: si recortar contenido, dibujar barras de desplazamiento o mostrar el contenido excedente en un elemento a nivel de bloque. Es un shorthand que engloba overflow-x y overflow-y.

Es la propiedad que controla que debe hacer la caja cuando su contenido se desborda del contenedor

Usando la propiedad overflow con un valor distinto a visible, valor por defecto, crearΓ‘ un nuevo contexto de formatos de bloques. Esto es tΓ©cnicamente necesario debido a que si un elemento flotante interceptara con otros forzarΓ­a a reajustar el contenido alrededor de los elementos que se interceden. El reajuste sucederΓ­a luego de cada desplazamiento, y llevarΓ­a a un desplazamiento demasiado lento.

Por defecto, el navegador desborda el contenido del elemento, sin embargo, nosotros podemos decidir que hacer:

  • visible: No se controla el desbordamiento, el contenido simplemente se desborda. Valor por defecto.

  • hidden: Oculta el contenido desbordado y las barras de desplazamiento del elemento.

  • clip: Igual que hidden, pero no permite desplazamiento mediante programaciΓ³n.

  • scroll: Oculta el contenido desbordado y muestra barras de desplazamiento.

  • auto: El navegador decide. Generalmente, aplica scroll.

Ten en cuenta que overflow-x aplica estos valores a la barra de desplazamiento horizontal, overflow-y a la barra de desplazamiento vertical, mientras que overflow puedes utilizarlo con un parΓ‘metro para indicar el mismo valor a ambos ejes, o con dos parΓ‘metros para indicar uno para overflow-x y otro para overflow-y respectivamente

Colapso de margenes

Ahora bien, cuando dos elementos de bloque HTML tienen mΓ‘rgenes verticales que se tocan entre sΓ­, estos dos mΓ‘rgenes colapsan en uno o se fusionan entre sΓ­, y aquΓ­ dominarΓ‘ el mΓ‘s grande.

La documentaciΓ³n de la W3C define el colapso de mΓ‘rgenes de la siguiente manera:

"En CSS, los márgenes adyacentes de dos o más bloques (que podrían o no ser hermanos) pueden combinarse para formar un único margen. Cuando los márgenes se combinan de esta manera decimos que colapsan, y el margen combinado resultante se denomina margen colapsado."

ΒΏCuando colapsan los margenes?

Los mΓ‘rgenes horizontales no colapsan nunca, solo los verticales, es decir, los mΓ‘rgenes top y bottom, y colapsan siempre que dos mΓ‘rgenes verticales cualesquiera son contiguos y se Β«tocanΒ», cuando no hay nada mΓ‘s entre ellos. Las situaciones de colapso se pueden clasificar en cuatro casos:

  1. Hermanos adyacentes

  2. Un contenedor y su primer elemento

  3. Un contenedor y su ΓΊltimo elemento

  4. Bloques vacΓ­os

El colapso de mΓ‘rgenes solo afecta al modelo de bloques, no afecta a otros modelos de display, por ejemplo al flex model (display: flex).

Hermanos adyacentes

Este ejemplo visual es la mejor manera de entenderlo:

.box-1 {
    margin-bottom: 40px;
    padding: 20px;
    border: solid 5px red;
}
.box-2 {
    margin-top: 40px;
    padding: 20px;
    border: solid 5px blue;
}

span {
    font-weight: bold;
}

Cuando los desarrolladores hace algo asΓ­, espera que el margen de la primera caja y la segunda sea de 80px (40px + 40px), pero en realidad es de 40px. Los dos mΓ‘rgenes se tocan entre sΓ­, por lo que se combinan o se colapsan el uno con el otro.

El margen inferior del elemento se colapsa con el margen superior del siguiente elemento. Ahora para empujar aΓΊn mΓ‘s, vamos a dar a nuestra primera caja un margen inferior (margin-bottom) de 100px

.box-1 {
    margin-bottom: 100px;
}
.box-2 {
    margin-top: 40px;
}

Como podemos observan en la imagen el margen mΓ‘s grande siempre gana, es decir, como la primera caja tiene un margen de 100px y la otra caja 40px el que termina ganando es el que tenga un valor superior, podemos decir que hay 100px de margen entre la primera y la segunda caja.

El mejor mΓ©todo o truco para solucionar esto, es utilizar siempre margin-bottom para separar elementos olvidarte de margin-top

Un contenedor padre y su primer elemento

En este ejemplo vamos a tener un header y dentro de el un encabezado <h1>.

<header class="header">
   <h1 class="title">Lupita code</h1>
</header>
body {
    margin: 0;
    font-family: arial;
    background-color: #ccc;
}

.header {
    height: 50px;
    background-color: steelblue;
}

Como podemos observar en la imagen hay un espacio entre la parte superior del viewport y el header, ese espacio extra no corresponde al body ya que si te fijas en el cΓ³digo CSS, el body tiene un margen con valor de 0. ΒΏAdivinas de dΓ³nde viene?

Ese margen tampoco es del header lo que nos lleva a concluir que ese margen le corresponde al encabezado <h1>, y si revisas la herramienta de desarrollo te puedes dar cuenta que el encabezado ya viene con un margen vertical de la hoja de estilo del navegador.

ΒΏRecuerdas cuando mencionΓ© sobre las hojas de estilo del navegador?

Alt Text

La soluciΓ³n es colocar un margin: 0 al <h1> y asΓ­ ya no se tiene esa separaciΓ³n. El resultado es el siguiente:

.title {
    margin: 0;
}

Ahora quiero agregar nuevamente un margin-top de 10px al <h1>

.title {
    margin: 0;
    margin-top: 20px;
}

Como puedes observar el header se moviΓ³, y se supone que solo le indicamos que se moviera el <h1>. Para que esto no ocurra, tenemos varias soluciones:

  1. AΓ±adir la declaraciΓ³n overflow: hidden al header.

  2. AΓ±adir un padding-top al header.

  3. AΓ±adir un border-top al header.

Si anΜƒadimos padding, border o espacio a los elementos de los ejemplos anteriores, no se aplicará el colapso. En otras palabras, una forma de deshacerse del comportamiento del colapso de márgenes consiste en anΜƒadir algún tipo de separación (borde, padding o espacio libre) entre los márgenes.

Un contenedor padre y su ΓΊltimo elemento.

De forma anΓ‘loga a lo que ocurre en el caso anterior con los mΓ‘rgenes superiores, los mΓ‘rgenes inferiores del contenedor y de su ΓΊltimo elemento tambiΓ©n colapsan en uno solo. Y tambiΓ©n como en el caso anterior, el colapso de mΓ‘rgenes no se produce si el borde o el padding del contenedor es mayor a cero.

<div class="parent">
   <div class="child">Here is a paragraph</div>
</div>
<div class="div">Outside the parent</div>
body {
    margin: 0;
    font-family: arial;
}

.parent {
    margin-bottom: 30px;
    background: #49b293;
    height: auto;
}
.child {
    margin-bottom: 50px;
    background: blue;
    height: 100px;
    width: 200px;
}

.div {
    background-color: red;
}

Como puedes observar al igual que pasa con el primeri hijo, aunque hayamos establecido un margin-bottom: 30px; al padre y un margin-bottom: 50px; al hijo estos, mΓ‘argenes se colapsen y al final solo queda el del hijo, puesto que es el mas grande.

Bloques vacΓ­os

Los mΓ‘rgenes verticales de un bloque vacΓ­o (sin height ni padding ni contenido) tambiΓ©n colapsan entre sΓ­. Por ejemplo, si tenemos un bloque vacΓ­o con un margen top de 40px y un margen bottom de 20px, el elemento ocuparΓ‘ una zona de 40px de altura al colapsar sus propios mΓ‘rgenes verticales:

<div class="box">Lorem, ipsum.</div>
<div class="empty"></div>
<div class="box">Lorem, ipsum.</div>
body {
    margin: 0;
    font-family: arial;
}

.box {
    margin: 0;
    height: 40px;
    padding: 10px;
    border: 2px solid;
    background: khaki;
}
.empty {
    margin-top: 40px;
    margin-bottom: 20px;
}

Bibliografia

Last updated