Elementos flotantes dentro de un div, flota fuera de div. ¿Por qué?

274

Digamos que tienes un div, dale un definido widthy ponle elementos, en mi caso uno imgy otro div.

La idea es que el contenido del contenedor divhará que el contenedor se divestire y sea un fondo para el contenido. Pero cuando hago esto, el contenido se divcontrae para adaptarse a los objetos no flotantes, y los objetos flotantes estarán completamente hacia afuera, o hacia la mitad, hacia la mitad, y no tendrán ninguna relación con el tamaño de lo grande div.

¿Por qué es esto? ¿Hay algo que me falta y cómo puedo obtener elementos flotantes para estirar el heightcontenido div?

DavidR
fuente

Respuestas:

398

Lo más fácil es poner overflow:hiddenel div padre y no especificar una altura:

#parent { overflow: hidden }

Otra forma es también flotar el div padre:

#parent { float: left; width: 100% }

Otra forma usa un elemento claro:

<div class="parent">
   <img class="floated_child" src="..." />
   <span class="clear"></span>
</div>

CSS

span.clear { clear: left; display: block; }
Doug Neiner
fuente
17
Funciona, pero ahora estoy dos veces más confundido: ¿hay una explicación para esto o es así?
DavidR
8
Sí, hay una explicación, pero desde entonces la he olvidado :( Es solo cómo es. overflow:hiddenObliga al navegador lo mejor que puede a contener los elementos secundarios de los padres. Es por eso que lo soluciona.
Doug Neiner
55
Creo que la explicación overflow: hiddenestá aquí: enlace . Y muchas gracias, funcionó para mí
Vikas Arora
66
@DavidR La explicación más fácil es que html / css es una pieza de tecnología anticuada, mal pensada y mal implementada. De hecho, este razonamiento explica muchas peculiaridades html / css que sin duda ha encontrado desde que hizo esta publicación.
Leve
1
Tenga en cuenta que overflow: hiddensolo ocultará cualquier parte de un elemento que fluya fuera del contenedor principal. Para mí, esto causó que ciertos fragmentos de texto se volvieran ilegibles.
Top Cat
160

Razón

El problema es que los elementos flotantes están fuera de flujo :

Un elemento se llama fuera de flujo si está flotando, en una posición absoluta o si es el elemento raíz.

Por lo tanto, no impactan los elementos circundantes como lo haría un elemento en flujo .

Esto se explica en 9.5 Flotadores :

Dado que un flotador no está en el flujo, las cajas de bloques no posicionadas creadas antes y después de la caja del flotador fluyen verticalmente como si el flotador no existiera. Sin embargo, los cuadros de línea actuales y posteriores creados junto al flotador se acortan según sea necesario para dejar espacio para el cuadro de margen del flotador.

ingrese la descripción de la imagen aquí

Esto también se especifica en 10.6 Cálculo de alturas y márgenes . Para bloques "normales" ,

Solo se tienen en cuenta los niños en el flujo normal (es decir, las cajas flotantes y las cajas posicionadas absolutamente se ignoran [...])

ingrese la descripción de la imagen aquí

Solución de Hacky: despacho

Una forma de resolver el problema es forzar a colocar un elemento en flujo debajo de todos los flotadores. Luego, la altura del padre crecerá para envolver ese elemento (y, por lo tanto, los flotadores también).

Esto se puede lograr usando la clearpropiedad :

Esta propiedad indica qué lados de los cuadros de un elemento pueden no ser adyacentes a un cuadro flotante anterior.

ingrese la descripción de la imagen aquí

Entonces, una solución es agregar un elemento vacío con clear: bothel último hermano de los flotadores

<div style="clear: both"></div>

Sin embargo, eso no es semántico. Por lo tanto, es mejor generar un pseudo-elemento al final del padre:

.clearfix::after {
  clear: both;
  display: block;
}

Existen múltiples variantes de este enfoque, por ejemplo, usar la sintaxis de dos puntos desaprobada :afterpara admitir navegadores antiguos, o usar otras pantallas de nivel de bloque comodisplay: table .

Solución: raíces BFC

Hay una excepción al comportamiento problemático definido al principio: si un elemento de bloque establece un Contexto de formato de bloque (es una raíz BFC), entonces también envolverá su contenido flotante.

De acuerdo con las alturas 'Auto' 10.6.7 para raíces de contexto de formato de bloque ,

Si el elemento tiene descendientes flotantes cuyo borde de margen inferior está por debajo del borde de contenido inferior del elemento, entonces la altura se incrementa para incluir esos bordes.

ingrese la descripción de la imagen aquí

Además, como se explica en 9.5 Flotadores , las raíces BFC también son útiles debido a lo siguiente:

El cuadro de borde de una tabla, un elemento reemplazado a nivel de bloque o un elemento en el flujo normal que establezca un nuevo contexto de formato de bloque [...] no debe superponerse al cuadro de margen de ningún flotante en el mismo contexto de formato de bloque que el elemento mismo .

ingrese la descripción de la imagen aquí

Un contexto de formato de bloque es establecido por

  • Bloquear cajas con overflowotras que visible, p. Ej.hidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
  • Bloque de contenedores que no son cajas de bloque: cuando displayse establece en inline-block, table-cello table-caption.

    .bfc-root {
      display: inline-block;
    }
  • Elementos flotantes: cuando floatse establece en lefto right.

    .bfc-root {
      float: left;
    }
  • Elementos posicionados absolutamente: cuando positionse establece en absoluteo fixed.

    .bfc-root {
      position: absolute;
    }

Tenga en cuenta que pueden tener efectos colaterales no deseados, como recortar contenido desbordado, calcular anchos automáticos con el algoritmo de reducción o ajuste o quedar fuera de flujo. Entonces, el problema es que no es posible tener un elemento de nivel de bloque en flujo con desbordamiento visible que establezca un BFC.

La pantalla L3 aborda estos problemas:

Creado las flowy los tipos de pantalla interior a disposición de flujo de expresar mejor los tipos de pantalla y crear un interruptor explícita para la fabricación de un elemento de un BFC raíz. (Esto debería eliminar la necesidad de hacks como y […])flow-root ::after { clear: both; }overflow: hidden

Lamentablemente, todavía no hay soporte para el navegador. Eventualmente podremos usar

.bfc-root {
  display: flow-root;
}
Oriol
fuente
1
Entonces, las cajas flotantes no son reconocidas por sus contenedores principales, por lo tanto, el colapso de la altura, pero son reconocidos por sus hermanos, ¿por qué la solución clara?
enlace simbólico
@symlink Sí, los contenedores principales no crecen para encerrar flotadores, a menos que sean raíces BFC. Los hermanos que no son raíces BFC no se ven directamente afectados por los bloques (pero sus cuadros de línea sí lo son). Sin embargo, el despeje los mueve por debajo de cualquier flotador anterior.
Oriol
"Los hermanos que no son raíces BFC no se ven directamente afectados por los bloques (pero sus cuadros de línea sí lo son)". - ¿Puedes aclarar esto por favor? ¿Quiere decir que en este jsFiddle: jsfiddle.net/aggL3Lk7/2 , la imagen en línea flotante no afecta el tramo (por lo tanto, el borde del tramo se superpone) pero la imagen está afectando el texto (que es el cuadro de línea) como se muestra por el hecho de que el texto no se superpone a la imagen?
enlace simbólico
1
@symlink Sí, exactamente. Bueno, en tu violín el borde pertenece al padre, pero sería básicamente el mismo para los hermanos: jsfiddle.net/aggL3Lk7/3
Oriol
1
Estoy de acuerdo. Esta debería ser la respuesta aceptada. Es interesante para mí que el W3 está llamando a la forma en que estamos obligados a codificar un "hack". Alguien la jodió mal.
DR01D
11

No falta nada. Float fue diseñado para el caso en el que desea que una imagen (por ejemplo) se asiente junto a varios párrafos de texto, de modo que el texto fluya alrededor de la imagen. Eso no sucedería si el texto "estirara" el contenedor. Su primer párrafo terminaría, y luego su próximo párrafo comenzaría debajo de la imagen (posiblemente varios cientos de píxeles debajo).

Y es por eso que estás obteniendo el resultado que eres.

Lucas Wilson-Richter
fuente
3
¿Cómo tiene eso algo que ver con el elemento flotante que estira correctamente la altura del padre?
Ligero
11

En algunos casos, es decir, cuando (si) solo está usando floatpara que los elementos fluyan en la misma "línea", puede usar

display: inline-block;

en vez de

float: left;

De lo contrario, usar un clearelemento al final funciona, incluso si puede ir en contra de la necesidad de un elemento para hacer lo que debería ser el trabajo de CSS.

LSerni
fuente
11

Aquí hay un enfoque más moderno:

.parent {display: flow-root;} 

No más soluciones claras.

ps Uso de desbordamiento: oculto; oculta la sombra de la caja así que ...

pendiente
fuente
Funciona también en Safari 11
pendiente el
7

Gracias LSerni lo resolviste por mí.

Lograr esto :

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+

Tienes que hacer esto :

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>
Flyout91
fuente
4

Como dice Lucas, lo que está describiendo es el comportamiento previsto para la propiedad flotante. Lo que confunde a muchas personas es que el flotador ha sido empujado más allá de su uso original previsto para compensar las deficiencias en el modelo de diseño CSS.

Eche un vistazo a Floatutorial si desea comprender mejor cómo funciona esta propiedad.

Sam Murray-Sutton
fuente
0

Puede hacerlo fácilmente, primero puede hacer que el div se flexione y aplique justificar el contenido hacia la derecha o hacia la izquierda y su problema está resuelto.

<div style="display: flex;padding-bottom: 8px;justify-content: flex-end;">
					<button style="font-weight: bold;outline: none;background-color: #2764ff;border-radius: 3px;margin-left: 12px;border: none;padding: 3px 6px;color: white;text-align: center;font-family: 'Open Sans', sans-serif;text-decoration: none;margin-right: 14px;">Sense</button>
				</div>

Vijay Tiwari
fuente