2008-11-24 18 views
5

Tengo un html muy simple. El div rojo está dentro del div azul y tiene un margen superior de 10 px. En navegadores que no sean, el cuadro azul está a 10 px de distancia de la parte superior de la ventana gráfica y el div rojo está en la parte superior del div azul. Lo que espero es el comportamiento ie: el div rojo debe estar a 10 px de distancia de la parte superior del div azul. ¿Por qué los navegadores no-ie se procesan así? (Supongo que el comportamiento incorrecto es el IE pero ¿por qué?)margen inesperado con html muy simple

Y, ¿cuál es la forma correcta de hacerlo?

why blank? http://img92.imageshack.us/img92/7662/blankmr7.jpg

<html> 
<head> 
<style> 
body { margin:0; padding:0; } 
.outer 
{ 
    background-color: #00f; 
    height: 50px;  
} 
.inner 
{ 
    height: 20px; 
    width: 20px; 
    background-color: #f00; 
    margin: 10px 0 0 10px; 
} 
</style> 
</head> 
<body> 
<div class="outer"> 
    <div class="inner"> 
    </div> 
</div> 
</body> 
</html> 

Respuesta

9

Tanto como strager's answer ya explica todo lo que necesita saber por qué sucede, es decir, que sucede de la misma manera que en los navegadores que no sean IE porque las especificaciones lo dicen, creo que escogió el presupuesto equivocado de la sección de the CSS 2.1 specification sobre collapsing margins.

El punto que cita explica cómo los márgenes pueden colapsar, no cómo pueden "moverse" a un elemento principal.

Esto es más bien lo que explica que:

  • Si los márgenes superior e inferior de una caja son adyacentes, entonces es posible que los márgenes se colapsen a través de él. En este caso, la posición del elemento depende de su relación con los otros elementos cuyos márgenes se están contrayendo.
    • Si los márgenes del elemento se contraen con el margen superior de sus padres, el borde del borde superior del cuadro se define como el mismo que el del padre.

O, en forma un poco más legible en el Mozilla developer documentation:

Padres y el primer/último hijo:

Si no hay frontera, el acolchado , contenido en línea o espacio libre para separar el margen superior de un bloque con el margen superior de su primer bloque secundario, o sin borde, relleno, contenido en línea, altura, altura mínima o máximo; Para separar el margen inferior de un bloque con el margen inferior de su último hijo, esos márgenes colapsan. El margen colapsado termina fuera del padre.

cuanto a cómo solucionarlo, probablemente me vaya para la solución overflow: autoChris Lloyd suggested (tanto como que puede tener efectos secundarios).

Pero eso depende de cómo sea exactamente el resto del código. En este ejemplo simple, puede cambiar fácilmente el margen en el elemento secundario a un relleno en el elemento primario.

O usted podría flotar el elemento secundario, o absolutamente posicionarlo ...

O qué tal una inversa clearfix si desea obtener realmente de lujo:

.outer:before { 
    content: "."; 
    display: block; 
    height: 0; 
    clear: both; 
    visibility: hidden; 
} 
+0

Sí, no hice mucha investigación al responder esta pregunta. Parece que eres menos vago que yo. Gracias por aclararlo. – strager

+0

Tuve la suerte de que obtuviera una cita incorrecta o me hubiera zambullido en las especificaciones para nada. ;) – mercator

4

Los márgenes se fusionan. La salida producida por IE es probablemente incorrecta.

En las especificaciones (que son abajo para mí en este momento):

Dos o más márgenes verticales adyacentes de las cajas de bloque en el colapso flujo normal. El ancho del margen resultante es el máximo de los anchos de margen adyacentes.

Puede usar bordes en lugar de márgenes, con el color del borde establecido en transparente.

3

Hay una respuesta muy apropiado a esta pregunta: overflow: auto;

<html> 
<head> 
<style> 
body { margin:0; padding:0; } 
.outer 
{ 
    background-color: #00f; 
    height: 50px; 
    overflow: auto; 
} 
.inner 
{ 
    height: 20px; 
    width: 20px; 
    background-color: #f00; 
    margin: 10px 0 0 10px; 
} 
</style> 
</head> 
<body> 
<div class="outer"> 
    <div class="inner"> 
    </div> 
</div> 
</body> 
</html> 
+0

Esto puede hacer que las barras de desplazamiento, lo que puede o puede no ser deseado. -1 para posibles efectos secundarios. – strager

+0

En ese caso, puede usar el desbordamiento: oculto; –

+0

Eso causa otro efecto secundario; ¿y si el contenido quería desbordarse? Creo que la solución de desbordamiento es un error en el navegador; No puedo ver nada en las especificaciones sobre el desbordamiento y los márgenes no negativos. – strager

0

Podría ser IE ve el DOM como div.inner tener div.outer ya que es nodo padre (y calcula desplazada con respecto a ella),
y que otros navegadores en su lugar tienen ambos respondiendo al elemento del cuerpo?

0

Ok, sin solución de auto desbordamiento:

<html> 
<head> 
<style> 
body { margin:0; padding:0; } 
.outer 
{ 
    background-color: #00f; 
    height: 50px; 
    border: 1px solid transparent; 
} 
.inner 
{ 
    height: 20px; 
    width: 20px; 
    background-color: #f00; 
    margin: 10px 0 0 10px; 
    padding: 0; 
} 
</style> 
</head> 
<body> 
<div class="outer"> 
    <div class="inner"> 
    </div> 
</div> 
</body> 
</html> 

El elemento interno es querer algo para empujar contra, y proporcionando un boder (o forzar al navegador a considerar el desbordamiento) hace esto.

+0

El problema es que ahora tiene un borde transparente de 1px :) probablemente funcione mejor si lo configura en 1px sólido # 00f. – Jimmy