previniendo margenes div dinamico contenido colapso colapsados alto ajustar css layout css-float margin

margenes - margin collapse css



CSS: soluciĆ³n limpia al problema de colapso de margen cuando se flota un elemento (7)

Ejemplo HTML + CSS:

<html> <body style="padding: 0; margin: 0;"> <div style="float: right;">first</div> <div style="margin-top: 2em;">second</div> </body> </html>

Comportamiento deseado: el first div flota en la parte superior derecha de la ventana. Comportamiento real: flota 2em por debajo de la posición deseada. Motivo: colapso del margen .

A pesar de identificar el problema, las soluciones que se me ocurren son como hackers:

  • cambie body estilo del body al margin: -1px 0 0 0; border-top: 1px solid; margin: -1px 0 0 0; border-top: 1px solid; .
  • inserte <div style="height: 1px; margin-bottom: -1px;"></div> antes first
  • inserte el <div> entre el first y el second

¿Hay una manera limpia e idiomática de evitar este problema?


SOLUCIÓN

agregar overflow: auto; o overflow: hidden; o overflow: scroll; tanto html como body tag

SI QUIERES SABER POR QUÉ

Crear el contexto de formato de bloque (BFC) en body etiqueta de body .

Por qué no funciona si agrego overflow: hidden; solo al body ?

Aquí es por qué:

W3C#block-formatting

Los flotantes, elementos absolutamente posicionados, bloquean contenedores (como bloques en línea, celdas de tabla y leyendas de tablas) que no son cuadros de bloques y bloquean cuadros con ''desbordamiento'' que no sean ''visibles'' ( excepto cuando ese valor se ha propagado a la ventana gráfica ) establecer nuevos contextos de formato de bloque para sus contenidos.

W3C#overflow :

Los UA deben aplicar el conjunto de propiedades ''overflow'' en el elemento raíz a la ventana gráfica.

Cuando el elemento raíz es un elemento HTML "HTML" o un elemento "html" XHTML, y ese elemento tiene un elemento HTML "BODY" o un elemento "body" XHTML como elemento secundario, los agentes de usuario deben aplicar la propiedad ''overflow'' desde el primer elemento secundario de ese tipo hasta la ventana gráfica, si el valor en el elemento raíz es ''visible'' .

El valor ''visible'' cuando se usa para la ventana gráfica debe interpretarse como ''auto''.

El elemento a partir del cual se propaga el valor debe tener un valor utilizado para ''desbordamiento'' de ''visible'' .

the first such child element y The element from which the value is propagated refieren a body etiqueta física en este caso.

En otras palabras, si agrega overflow: hidden; o overflow: auto; o overflow: scroll; al body mientras el valor de la propiedad de overflow de html es visible , el valor de la propiedad de overflow del body ( hidden o auto o scroll ) se propagará a la ventana gráfica. De acuerdo con la primera cita del W3C, el body no establecería un nuevo contexto de formato de bloque.

Sin embargo, si agrega overflow: hidden; o overflow: auto; o overflow: scroll; a html , el valor de overflow de ''cuerpo'' no se propagaría y, por lo tanto, establecería un nuevo contexto de formato de bloque.


Agregar float: left; a la segunda div.

fiddle


Agregar overflow: hidden; para el body debería resolver tu problema. Define un nuevo contexto de formato de bloque como se describe en este artículo: La magia del desbordamiento: oculta .

Demostración de jsFiddle (la etiqueta de body se agrega automáticamente por jsFiddle, es por eso que no la he incluido en el marcado HTML)

ACTUALIZACIÓN (gracias a @clairesuzy): esta solución no funciona si el body tiene padding: 0 . Hasta que pueda encontrar una mejor manera, solo puedo sugerir agregar un envoltorio alrededor de los dos divs (al menos merezco ahora @ Marcel''s downwote :)), que aún creo que es más limpio que las soluciones publicadas por el OP. Normalmente, siempre agrego un envoltorio alrededor de materia flotante (hace que sea más fácil manejar navegadores antiguos la mayor parte del tiempo), la mayoría de las veces no necesita ser agregado deliberadamente, porque es lógico y semánticamente necesario.

Entonces, por ahora, puedo pensar en esto:

<body style="padding: 0; margin: 0;"> <div id="container" style="overflow: hidden;"> <div style="float: right;">first</div> <div style="margin-top: 2em;">second</div> </div> </body>

jsFiddle Demo

ACTUALIZACIÓN 2 : Después de pensarlo bien, y leer comentarios, realmente creo que el overflow: hidden (o cualquier otra cosa que no sea overflow: visible ) en el contenedor es la solución correcta. La única excepción en que no funcionó para mí es configurarlo en el elemento del body , que de todos modos es una situación muy rara. En estas situaciones raras, puede intentar usar position: absolute; top: 0; right: 0; position: absolute; top: 0; right: 0; en lugar de flotar

Otra solución posible: también he encontrado esa display: inline-block; width: 100%; configuración display: inline-block; width: 100%; display: inline-block; width: 100%; en el body funciona de hecho.

jsFiddle Demo


En el div principal, agregue este #parent {padding 1px 0; } #parent {padding 1px 0; } este fue un gran problema para mí y me llevó para siempre encontrar una solución. Vi en una publicación como 2 años y esto solucionó el colapso.


Las especificaciones W3C describen esto sobre los márgenes de colapso:

"En esta especificación, la expresión que colapsa los márgenes significa que los márgenes adyacentes (no hay contenido no vacío, relleno o áreas de borde, o espacio separado para separarlos) de dos o más recuadros (que pueden estar uno junto al otro o anidados) se combinan para formar un solo margen ".

http://www.w3.org/TR/CSS21/box.html#collapsing-margins

La mejor forma de lidiar con los márgenes colapsables es simplemente agregar un píxel al margen superior o inferior del elemento que tiene el margen contraído.

si el margen se derrumbaba en la parte superior ... entonces:

#element-with-collapsed-margin { padding-top:1px; }

o border-top arreglaría esto también

#element-with-collapsed-margin { border-top:1px solid transparent; }

si su margen inferior está contraído, debería agregar relleno al fondo: 1px; o borde superior: 1px sólido transparente;

básicamente, cualquier borde o relleno en la parte superior o inferior impedirá que los márgenes colapsen cuando los tenga uno encima del otro o incluso cuando tenga elementos anidados dentro de otro que tengan un colapso de margen

buena referencia:

http://reference.sitepoint.com/css/collapsingmargins

..


Otro truco que puedes usar cuando overflow:hidden no es adecuado:

.clr:before, .clr:after { display: table; content: " "; clear: both; font-size: 0; }

Este fragmento tiene el efecto secundario de contener todas las carrozas también.


Puede ser extraño, pero en las versiones nuevas de Chrome y Mozilla puede lograr el comportamiento deseado (el primer div se encuentra en la parte superior derecha) agregando wrapper div con borde

<html> <body style="padding: 0; margin: 0;"> <div style="border: 1px solid black"> <div style="float: right;">first</div> <div style="margin-top: 2em;">second</div> </div> </body> </html>