margenes etiqueta ejemplos colapso html margin css

html - etiqueta - ¿Por qué este estilo de margen superior de CSS no funciona?



margenes en html5 (11)

Intento agregar valores de margen en un div dentro de otro div. Todo funciona bien, excepto el valor superior, parece ser ignorado. ¿Pero por qué?

Lo que esperaba:

Lo que consigo:

Código:

#outer { width: 500px; height: 200px; background: #FFCCCC; margin: 50px auto 0 auto; display: block; } #inner { background: #FFCC33; margin: 50px 50px 50px 50px; padding: 10px; display: block; }

<div id="outer"> <div id="inner"> Hello world! </div> </div>

W3Schools no tiene ninguna explicación de por qué el margen se comporta de esta manera.


¿Has probado? Importante antes de todo, lo forzará todo:

margin:50px 50px 50px 50px !important;


En realidad, está viendo que el margen superior del elemento #inner se collapse en el borde superior del elemento #outer , dejando solo intacto el margen #outer (aunque no se muestra en sus imágenes). Los bordes superiores de ambas cajas están alineados entre sí porque sus márgenes son iguales.

Aquí están los puntos relevantes de la especificación W3C:

8.3.1 Márgenes colapsados

En CSS, los márgenes adyacentes de dos o más cuadros (que pueden ser o no hermanos) se pueden combinar para formar un solo margen. Se dice que los márgenes que se combinan de esta manera se colapsan , y el margen combinado resultante se llama margen colapsado .

Los márgenes verticales adyacentes colapsan [...]

Dos márgenes son contiguos si y solo si:

  • ambos pertenecen a cuadros de nivel de bloque en flujo que participan en el mismo contexto de formato de bloque
  • Sin cajas de línea, sin espacio libre, sin relleno y sin bordes separarlos
  • ambos pertenecen a bordes de caja adyacentes verticalmente, es decir, forman uno de los siguientes pares:
    • margen superior de una caja y margen superior de su primer elemento secundario en flujo

La razón por la que hacer cualquiera de las siguientes acciones evita que se colapse el margen:

  • Flotando cualquiera de tus div elementos.
  • Haciendo cualquiera de tus elementos div línea.
  • Configuración del overflow de #outer en auto (o cualquier otro valor que no sea visible )

Es porque:

  • Los márgenes entre una caja flotante y cualquier otra caja no se colapsan (ni siquiera entre una flotación y sus hijos en flujo).
  • Los márgenes de los elementos que establecen nuevos contextos de formato de bloque (como flotadores y elementos con ''desbordamiento'' que no sean ''visibles'') no se colapsan con sus elementos secundarios en flujo.
  • Los márgenes de las cajas de bloque en línea no se colapsan (ni siquiera con sus hijos en flujo).

Los márgenes izquierdo y derecho se comportan como se espera porque:

Los márgenes horizontales nunca colapsan.


Intente usar display: inline-block; en el div interior

#outer { width:500px; height:200px; background:#FFCCCC; margin:50px auto 0 auto; display:block; } #inner { background:#FFCC33; margin:50px 50px 50px 50px; padding:10px; display:inline-block; }


Lo que mencionó @BoltClock es bastante sólido. Y aquí solo quiero agregar varias soluciones más para este problema. Compruebe este margen w3c_collapsing . Las partes verdes son el pensamiento potencial de cómo se puede resolver este problema.

Solución 1

Los márgenes entre una caja flotante y cualquier otra caja no se colapsan (ni siquiera entre una flotación y sus hijos en flujo).

eso significa que puedo agregar float:left a #outer o #inner demo1 .

También tenga en cuenta que float invalidaría el auto en el margen.

Solucion 2

Los márgenes de los elementos que establecen nuevos contextos de formato de bloque (como flotadores y elementos con ''desbordamiento'' que no sean ''visibles'') no se colapsan con sus elementos secundarios en flujo.

#outer de lo visible , pongamos overflow: hidden en #outer . Y de esta manera parece bastante simple y decente. Me gusta.

#outer{ width: 500px; height: 200px; background: #FFCCCC; margin: 50px auto; overflow: hidden; } #inner { background: #FFCC33; height: 50px; margin: 50px; }

Solucion 3

Los márgenes de las cajas con posición absoluta no se colapsan (ni siquiera con sus hijos en flujo).

#outer{ width: 500px; height: 200px; background: #FFCCCC; margin: 50px auto; position: absolute; } #inner{ background: #FFCC33; height: 50px; margin: 50px; }

o

#outer{ width: 500px; height: 200px; background: #FFCCCC; margin: 50px auto; position: relative; } #inner { background: #FFCC33; height: 50px; margin: 50px; position: absolute; }

Estos dos métodos romperán el flujo normal de div

Solucion 4

Los márgenes de las cajas de bloque en línea no se colapsan (ni siquiera con sus hijos en flujo).

es lo mismo que @enderskill

Solucion 5

El margen inferior de un elemento de nivel de bloque en flujo siempre se colapsa con el margen superior de su siguiente hermano de nivel de bloque en flujo, a menos que ese hermano tenga espacio libre.

Esto no tiene mucho trabajo que hacer con la pregunta, ya que es el margen de colapso entre hermanos. generalmente significa que si un cuadro superior tiene margin-bottom: 30px y un cuadro hermano tiene margin-top: 10px . El margen total entre ellos es 30px lugar de 40px .

Solucion 6

El margen superior de un elemento de bloque de flujo colapsa con su primer margen superior de nivel de bloque de flujo de flujo si el elemento no tiene borde superior, sin relleno superior y el niño no tiene espacio libre.

Esto es muy interesante y solo puedo agregar una línea de borde superior

#outer{ width: 500px; height: 200px; background: #FFCCCC; margin: 50px auto; border-top: 1px solid red; } #inner { background: #FFCC33; height: 50px; margin: 50px; }

Y también <div> está en el nivel de bloque por defecto, por lo que no tiene que declararlo a propósito. Lo siento por no poder publicar más de 2 enlaces e imágenes debido a mi reputación de novato. Al menos sabes de dónde viene el problema la próxima vez que veas algo similar.


No estoy seguro de por qué lo que tienes no funciona, pero puedes agregar

overflow: auto;

a la div exterior


No responde al "por qué" (tiene que ser algo con un margen de colapso), pero parece que la forma más fácil / lógica de hacer lo que se intenta hacer es simplemente agregar el padding-top a la división externa :

http://jsfiddle.net/hpU5d/1/

Nota menor: no debería ser necesario configurar un div para display:block; a menos que haya algo más en tu código que diga que no se bloquee.


No sé exactamente por qué, pero cambiando el CSS interno a

display:inline-block;

parece funcionar;


Si agrega algún relleno a #outer , funciona.

Demo

#outer { width:500px; height:200px; background:#FFCCCC; margin:50px auto 0 auto; display:block; padding-top:1px; }


Supongo que establecer la propiedad de posición de la división #inner en relativa también puede ayudar a lograr el efecto. Pero de todos modos probé el código original pegado en la Pregunta en IE9 y en el último Google Chrome y ya dan el efecto deseado sin ninguna modificación.


Use padding-top:50px para div exterior. Algo como esto:

#outer { width:500px; height:200px; background:#FFCCCC; margin:50px auto 0 auto; display:table;}

Nota: el relleno aumentará el tamaño de tu div. En este caso, si el tamaño de tu div es importante, quiero decir si debe tener una altura específica. disminuir la altura en 50px .:

#outer { width:500px; height:150px; background:#FFCCCC; margin:50px auto 0 auto; display:table;}


prueba esto:

#outer { width:500px; height:200px; background:#FFCCCC; margin:50px auto 0 auto; display:table; } #inner { background:#FFCC33; margin:50px 50px 50px 50px; padding:10px; display:block; }​

http://jsfiddle.net/7AXTf/

Buena suerte