2010-04-21 17 views
105

Tengo un encabezado div como el primer elemento en mi envoltorio div, pero cuando agrego un margen superior a un h1 dentro del encabezado div empuja todo el encabezado div hacia abajo. Me doy cuenta de que esto sucede cada vez que aplico un margen superior al primer elemento visible en una página.Margin-Top push div exterior abajo

Aquí hay un fragmento de código de muestra. ¡Gracias!

div#header{ 
 
\t width: 100%; 
 
\t background-color: #eee; 
 
\t position: relative; 
 
} 
 

 
div#header h1{ 
 
\t text-align: center; 
 
\t width: 375px; 
 
\t height: 50px; 
 
\t margin: 50px auto; 
 
\t font-size: 220%; 
 
\t background: url('../../images/name_logo.png') no-repeat; 
 
}
<div id="header"> 
 
\t <h1>Title</h1> 
 
\t <ul id="navbar"></ul> 
 
</div>

Respuesta

159

poner overflow:auto en el padre div
see more in this link

+26

'overflow: hidden' es mejor para el 90% de los casos. – vsync

+1

¿Por qué se desbordará: oculto será mejor? – peterchon

+5

@peterchon - porque el auto puede causar barras de desplazamiento – vsync

27

que no tienen una explicación sólida de por qué sucede esto, pero me he fijado esto cambiando la top-margin-top-padding, o la adición de display: inline-block al estilo elemento.

EDIT: Esta es mi teoría

Tengo la sensación de que tiene algo que ver con la forma en márgenes se contraen (combinado).

de W3C Collapsing Margins:

En esta memoria descriptiva, la expresión márgenes colapso significa que márgenes adyacentes (no hay áreas de contenido, relleno o borde no vacíos o despeje separados) de dos o más las casillas (que pueden estar próximas a una otra o anidadas) se combinan para formar un margen único de .

Mi teoría es que, dado que el primer elemento está al lado del cuerpo de los dos márgenes se combinan y se aplican al cuerpo: esto obliga el contenido del cuerpo para iniciar por debajo del margen aplicado se derrumbó en el cumplimiento de la box model.

hay situaciones en que los márgenes no se colapsan que podría valer la pena jugar con (de Collapsing Margins):

* floated elements 
* absolutely positioned elements 
* inline-block elements 
* elements with overflow set to anything other than visible (They do not collapse margins with their children.) 
* cleared elements (They do not collapse their top margins with their parent block’s bottom margin.) 
* the root element 
+3

Además, el relleno o borde en el elemento con margen colapsado (el interior) lo desenredará. – Anonymous

+0

@Anonymous: ¡gracias! Todas las soluciones mencionadas anteriormente eran inaceptables o no funcionaban para mí. – mik01aj

+0

Esto funcionó para mí: tenía elementos absolutos (un menú desplegable) en mi contenedor, por lo que se desbordaba: el auto no funcionaba. – mwilcox

13

Estos son algunos de los formas de evitar el colapso de los márgenes entre elementos padre-hijo. Utilice el que encaja mejor con el resto de su estilo:

  • Conjunto display distinto de block.
  • Conjunto float en otro que none.
  • Elimine el margen y, en su lugar, use padding. Por ejemplo, si tenía margin-top: 10px, reemplace con padding-top: 10px;.
  • Retire el margen, y usar en su lugar position (absolute o relative) con atributos top, bottom, etc. Por ejemplo, si tiene margin-top: 10px, reemplace con position: relative; top: 10px;.
  • Agregue padding o border en el lado donde se están contrayendo los márgenes, al elemento principal. El borde puede ser 1px y transparente.
  • Conjunto overflow a otro que visible al elemento principal.
0

Funcione con este problema hoy.

overflow: hidden no funcionó como se esperaba cuando me siguieron más elementos.

Así que traté de cambiar la propiedad de visualización del div principal y display: flex funcionó !!!

Espero que esto ayude a alguien. :)

0

Añadiendo un poco de relleno al elemento principal superior puede solucionar este problema.

.parent{ 
 
    padding-top: 0.01em; 
 
}

Esto es útil si se necesita un elemento dentro de la matriz para ser visible fuera del elemento padre, como si va a crear un efecto de superposición.

2

display: flex funcionarán en este caso. Proporcione el elemento padre display: flex; y luego dé un margen según su requisito a la etiqueta h1.

0

Sé que este es un problema antiguo, lo he encontrado muchas veces. El problema es que todas las soluciones aquí son cortes que potencialmente podrían tener consecuencias no deseadas.

En primer lugar, hay una explicación fácil para el problema de raíz. Debido a la forma en que funciona el colapso de margen, si el primer elemento dentro de un contenedor tiene un margen superior, ese margen superior se aplica de manera efectiva al propio contenedor padre. Puede probar esto por su cuenta de la siguiente manera:

<div> 
    <h1>Test</h1> 
</div> 

En un depurador, abrir esto y pase el div. Notarás que el div mismo en realidad se ubica donde el margen superior del elemento H1 detiene. Este comportamiento es intencionado por el navegador.

Así que hay una solución fácil para esto sin tener que recurrir a hacks extraños, como la mayoría de los mensajes aquí (sin insultos, es la verdad) - simplemente vuelve a la explicación original - ...if the first element inside a container has a top margin... - A continuación, por lo tanto, necesitaría el primer elemento en un contenedor en NO tienen un margen superior. Está bien, pero ¿cómo lo haces sin agregar elementos que no interfieran semánticamente con tu documento?

¡Fácil! Pseudo-elementos! Podrías hacer esto a través de una clase o un mixin predefinido.Añadir un :before pseudo-elemento:

CSS a través de una clase:

.top-margin-fix:before { 
    content: ' '; 
    display: block; 
    width: 100%; 
    height: .0000001em; 
} 

Con esto, siguiendo el ejemplo de marcado anterior deberá modificar su div como tal:

<div class="top-margin-fix"> 
    <h1>Test</h1> 
</div> 

Por qué ¿Esto funciona?

El primer elemento de un contenedor, si no tiene margen superior, establece la posición del inicio del margen superior del siguiente elemento. Al agregar un pseudo-elemento :before, el navegador realmente agrega un elemento no semántico (en otras palabras, bueno para SEO) al contenedor principal antes de, su primer elemento.

P. ¿Por qué la altura: .0000001em?

A. Se requiere una altura para que el navegador empuje el elemento de margen hacia abajo. Esta altura es efectivamente cero, pero aún le permitirá agregar relleno al contenedor principal. Dado que es efectivamente cero, tampoco tendrá un efecto en el diseño del contenedor. Hermosa.

Ahora puede agregar una clase (o mejor, en SASS/LESS, mixin!) Para solucionar este problema en lugar de agregar estilos de visualización extraños que causarán consecuencias inesperadas cuando quiera hacer otras cosas con sus elementos, a propósito eliminando los márgenes en los elementos y/o reemplazándolo con relleno, o estilos de posición/flotación extraños que realmente no están destinados a resolver este problema.

Cuestiones relacionadas