margen inesperado con html muy simple

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é?)

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

¿por qué en blanco? http://img92.imageshack.us/img92/7662/blankmr7.jpg

   body { margin:0; padding:0; } .outer { background-color: #00f; height: 50px; } .inner { height: 20px; width: 20px; background-color: #f00; margin: 10px 0 0 10px; }    

Por mucho que la respuesta de Strager ya explique todo lo que necesita saber sobre por qué ocurre, es decir, que sucede de la misma manera que en los navegadores que no sean IE porque las especificaciones lo dicen, creo que eligió la cita incorrecta de la sección de la especificación de CSS 2.1 sobre los márgenes colapsables .

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

Esto es más bien lo que lo explica:

  • Si los márgenes superior e inferior de una caja son contiguos, entonces es posible que los márgenes colapsen a través de ella. 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 están contraídos 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 una forma ligeramente más legible para los humanos en la documentación del desarrollador de Mozilla :

Padre y primer / último hijo:

Si no hay borde, relleno, 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 – Altura para separar el margen inferior de un bloque con el margen inferior de su último hijo, luego esos márgenes colapsan. El margen colapsado termina fuera del padre.

En cuanto a la forma de solucionarlo, probablemente iría por el overflow: auto solución overflow: auto sugerida por Chris Lloyd (por mucho que eso pueda tener efectos secundarios).

Pero eso depende de cómo sea exactamente el rest del código. En este sencillo ejemplo, puede simplemente cambiar el margen en el elemento secundario por un relleno en el elemento primario.

O puede flotar el elemento secundario o posicionarlo absolutamente …

O qué tal un clearfix inverso si quieres ser realmente elegante:

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

Los márgenes se están fusionando. La salida producida por IE es probablemente incorrecta.

En las especificaciones (que están mal para mí en este momento):

Dos o más márgenes verticales contiguos de cajas de bloques en el colapso de 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 color de borde establecido en transparente.

Hay una respuesta bastante adecuada a esta pregunta: overflow: auto;

      

¿Podría ser IE ve el DOM como div.inner teniendo div.outer como su nodo padre (y calcula el desplazamiento de él),
y que otros navegadores en su lugar tienen ambos respondiendo al elemento del cuerpo?

Ok, solución sin desbordamiento automático:

      

El elemento interno quiere algo contra lo que presionar, y proporcionar un boder (u obligar al navegador a considerar el desbordamiento) hace esto.