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.
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-sibling {
border: 3px solid green;
}
.block-sibling:after {
content: 'Block sibling';
color: green;
}
.float {
float: left;
border: 3px solid red;
height: 90px;
width: 150px;
z-index: 1;
}
.float:after {
content: 'Float';
color: red;
}
<div class="float"></div>
<div class="block-sibling">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor.
</div>
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 [...])
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent:after {
content: 'Block parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 130px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
<div class="block-parent">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
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 clear
propiedad :
Esta propiedad indica qué lados de los cuadros de un elemento pueden no
ser adyacentes a un cuadro flotante anterior.
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent:after {
content: 'Block parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 84px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
.clear {
clear: both;
text-align: center;
height: 37px;
border: 3px dashed pink;
}
.clear:after {
position: static;
content: 'Block sibling with clearance';
color: pink;
}
<div class="block-parent">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra.
<div class="clear"></div>
</div>
Entonces, una solución es agregar un elemento vacío con clear: both
el ú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 :after
para 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.
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent.bfc-root:after {
content: 'BFC parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 127px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
.bfc-root {
overflow: hidden;
}
<div class="block-parent bfc-root">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
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 .
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-sibling {
border: 3px solid green;
}
.block-sibling.bfc-root:after {
content: 'BFC sibling';
color: green;
}
.float {
float: left;
border: 3px solid red;
height: 90px;
width: 150px;
z-index: 1;
}
.float:after {
content: 'Float';
color: red;
}
.bfc-root {
overflow: hidden;
}
<div class="float"></div>
<div class="block-sibling bfc-root">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
</div>
Un contexto de formato de bloque es establecido por
Bloquear cajas con overflow
otras que visible
, p. Ej.hidden
.bfc-root {
overflow: hidden;
/* display: block; */
}
Bloque de contenedores que no son cajas de bloque: cuando display
se establece en inline-block
, table-cell
o table-caption
.
.bfc-root {
display: inline-block;
}
Elementos flotantes: cuando float
se establece en left
o right
.
.bfc-root {
float: left;
}
Elementos posicionados absolutamente: cuando position
se establece en absolute
o 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 flow
y 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;
}