Margen en elemento hijo mueve el elemento padre

Tengo un div ( padre ) que contiene otro div ( hijo ). Parent es el primer elemento del body sin un estilo CSS en particular. Cuando establezco

 .child { margin-top: 10px; } 

El resultado final es que la parte superior de mi hijo todavía está alineada con el padre. En lugar de cambiar al niño por 10px hacia abajo, mi padre se mueve 10px hacia abajo.

Mi DOCTYPE está configurado para XHTML Transitional .

¿Que me estoy perdiendo aqui?

editar 1
Mi padre necesita tener dimensiones estrictamente definidas porque tiene un fondo que debe mostrarse debajo de él de arriba a abajo (píxel perfecto). Entonces establecer márgenes verticales es un no ir .

editar 2
Este comportamiento es el mismo en FF, IE y CR.

Se encontró una alternativa en Elementos secundarios con márgenes dentro de DIV. También puede agregar:

 .parent { overflow: auto; } 

o:

 .parent { overflow: hidden; } 

Esto evita que los márgenes colapsen . El borde y el relleno hacen lo mismo. Por lo tanto, también puede usar lo siguiente para evitar un colapso en el margen superior:

 .parent { padding-top: 1px; margin-top: -1px; } 

Actualización por petición popular: el objective de los márgenes colapsables es manejar el contenido de texto. Por ejemplo:

  

Title!

Title!

Paragraph

Title!

Paragraph

  • list item

Debido a que el navegador contrae los márgenes, el texto aparecerá como es de esperar, y las tags del envoltorio

no influyen en los márgenes. Cada elemento asegura que tiene espacio a su alrededor, pero el espacio no se duplicará. Los márgenes de

y

no se sumrán, sino que se deslizarán unos sobre otros (colapsarán). Lo mismo ocurre con el elemento

y

    .

    Tristemente, con diseños modernos, esta idea puede morderte cuando explícitamente quieres un contenedor. Esto se llama un nuevo contexto de formato de bloque en CSS speak. El truco de overflow o margen le dará eso.

    Este es un comportamiento normal (entre las implementaciones del navegador al menos). El margen no afecta la posición del niño en relación con su padre, a menos que el padre tenga relleno, en cuyo caso la mayoría de los navegadores agregarán el margen del niño al margen del padre.

    Para obtener el comportamiento que desea, necesita:

     .child { margin-top: 0; } .parent { padding-top: 10px; } 

    Aunque todas las respuestas solucionan el problema, pero vienen con intercambios / ajustes / compromisos como

    • floats , tienes que flotar elementos
    • border-top , Esto empuja al padre al menos 1px hacia abajo, que luego debe ajustarse con la introducción del margen -1px en el elemento principal. Esto puede crear problemas cuando parent ya tiene margin-top en unidades relativas.
    • padding-top , el mismo efecto que usar border-top
    • overflow: hidden , no se puede usar cuando el padre debe mostrar contenido desbordado, como un menú desplegable
    • overflow: auto , presenta barras de desplazamiento para el elemento padre que tiene contenido desbordado (intencionalmente) (como sombras o el triángulo de la punta de la herramienta)

    El problema se puede resolver mediante el uso de pseudo elementos CSS3 de la siguiente manera

     .parent::before { clear: both; content: ""; display: table; margin-top: -1px; height: 0; } 

    https://jsfiddle.net/hLgbyax5/1/

    agregar display:inline-block estilo display:inline-block en display:inline-block al elemento hijo

    el elemento padre no debe estar vacío al menos poner   antes del elemento hijo.

    Esto es lo que funcionó para mí

     .parent { padding-top: 1px; margin-top: -1px; } .child { margin-top:260px; } 

    http://jsfiddle.net/97fzwuxh/

    El margin de los elementos contenidos en .child está colapsando.

        

    &

    &

    En este ejemplo, p recibe un margin de los estilos predeterminados del navegador. El font-size predeterminado del navegador suele ser de 16 px. Al tener un margin-top a más de 16 píxeles en #child , comienza a notar que se mueve de posición.

    También tuve este problema, pero preferí evitar los márgenes negativos, así que puse un

    alrededor de todo, que tiene almohadillas en lugar de márgenes. Por supuesto, esto significa más divitis, pero es probablemente la forma más limpia de hacerlo bien.

    Curiosamente, mi solución favorita para este problema aún no se menciona aquí: usar flotadores.

    html:

     

    css:

     .parent{width:100px; height:100px;} .child{float:left; margin-top:20px; width:50px; height:50px;} 

    Véalo aquí: http://codepen.io/anon/pen/Iphol

    tenga en cuenta que en caso de que necesite altura dinámica en el elemento principal, también debe flotar, simplemente reemplace la height:100px; por float:left;

    Una solución alternativa que encontré antes de saber que la respuesta correcta era agregar un borde transparente al elemento principal.

    Sin embargo, su caja usará píxeles extra …

     .parent { border:1px solid transparent; } 

    Descubrí que, dentro de tu .css> si configuras la propiedad de visualización de un elemento div como inline-block, se soluciona el problema. y el margen funcionará como se espera.

    Usar top vez de margin-top es otra posible solución, si corresponde.

    Una solución pura de CSS

    Use el siguiente código para anteponer un primer hijo sin contenido al div que se mueve involuntariamente:

     .parent:before {content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;} 

    La ventaja de este método es que no necesita cambiar el CSS de ningún elemento existente y, por lo tanto, tiene un impacto mínimo en el diseño. Junto a esto, el elemento que se agrega es un pseudo-elemento, que no está en el árbol DOM.

    El soporte para pseudo-elementos es muy extendido: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+ e IE 8+. Esto funcionará en cualquier navegador moderno (tenga cuidado con el más nuevo ::before , que no es compatible con IE8).

    Contexto

    Si el primer hijo de un elemento tiene un margin-top , el padre ajustará su posición como una forma de contraer los márgenes redundantes. ¿Por qué? Es solo así.

    Dado el siguiente problema:

      
    Hello world!

    Puede solucionarlo agregando un elemento secundario, como un espacio simple. Pero todos odiamos agregar espacios para lo que es un problema de solo diseño. Por lo tanto, use la propiedad white-space para falsificar contenido.

      
    Hello world!

    Donde position: relative; asegura el posicionamiento correcto de la solución. Y white-space: pre; hace que no tengas que agregar ningún contenido, como un espacio en blanco, al arreglo. Y height: 0px;width: 0px;overflow: hidden; se asegura de que nunca verás la solución.

    Es posible que deba agregar line-height: 0px; o max-height: 0px; para asegurar que la altura sea realmente cero en navegadores IE antiguos (no estoy seguro). Y, opcionalmente, podría agregar a él en los viejos navegadores IE, si no funciona.

    En resumen, puede hacer todo esto solo con CSS (lo que elimina la necesidad de agregar un elemento secundario real al árbol HTML DOM):

      
    Hello world!

    Para evitar que “Div parent” use el margen de “div child”:
    En el padre use estos css:

    • Flotador
    • Relleno
    • Frontera
    • Rebosar