Raison
Le problème est que les éléments flottants sont hors du flux :
Un élément est appelé hors flux s'il est flottant, absolument positionné ou s'il est l'élément racine.
Par conséquent, ils ne touchent pas des éléments entourant comme en flux élément serait.
Ceci est expliqué dans 9.5 Flotteurs :
Puisqu'un flottant n'est pas dans le flux, les blocs de blocs non positionnés créés avant et après le flotteur circulent verticalement comme si le flotteur n'existait pas. Cependant, les zones de ligne actuelles et suivantes créées à côté du flottant sont raccourcies si nécessaire pour faire de la place à la zone de marge du flottant.
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>
Ceci est également spécifié dans 10.6 Calcul des hauteurs et des marges . Pour les blocs "normaux" ,
Seuls les enfants dans le flux normal sont pris en compte (c'est-à-dire que les boîtes flottantes et les boîtes absolument positionnées sont ignorées […])
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>
Solution Hacky: dégagement
Un moyen de résoudre le problème consiste à forcer certains éléments entrants à être placés sous tous les flotteurs. Ensuite, la hauteur du parent augmentera pour envelopper cet élément (et donc les flotteurs aussi).
Ceci peut être réalisé en utilisant la clear
propriété :
Cette propriété indique quels côtés de la ou des boîtes d'un élément ne peuvent pas
être adjacents à une boîte flottante antérieure.
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>
Donc, une solution consiste à ajouter un élément vide avec clear: both
comme dernier frère des flotteurs
<div style="clear: both"></div>
Cependant, ce n'est pas sémantique. Mieux vaut donc générer un pseudo-élément à la fin du parent:
.clearfix::after {
clear: both;
display: block;
}
Il existe plusieurs variantes de cette approche, par exemple en utilisant la syntaxe :after
à deux points obsolète pour prendre en charge les anciens navigateurs, ou en utilisant d'autres affichages au niveau du bloc comme display: table
.
Solution: racines BFC
Il existe une exception au comportement problématique défini au début: si un élément de bloc établit un contexte de formatage de bloc (est une racine BFC), il encapsulera également son contenu flottant.
Selon les hauteurs 10.6.7 «Auto» pour les racines de contexte de formatage de bloc ,
Si l'élément a des descendants flottants dont le bord de marge inférieur est en dessous du bord de contenu inférieur de l'élément, la hauteur est augmentée pour inclure ces bords.
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>
De plus, comme expliqué dans 9.5 Floats , les racines BFC sont également utiles pour les raisons suivantes:
La zone de bordure d'une table, un élément remplacé au niveau du bloc ou un élément dans le flux normal qui établit un nouveau contexte de mise en forme de bloc […] ne doit pas chevaucher la zone de marge des flottants dans le même contexte de mise en forme de bloc que l'élément lui-même .
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 contexte de formatage de bloc est établi par
Boîtes de bloc avec overflow
autre que visible
, par exemplehidden
.bfc-root {
overflow: hidden;
/* display: block; */
}
Bloquer les conteneurs qui ne sont pas des blocs: lorsque display
est défini sur inline-block
, table-cell
ou table-caption
.
.bfc-root {
display: inline-block;
}
Éléments flottants: quand float
est réglé sur left
ou right
.
.bfc-root {
float: left;
}
Éléments positionnés de manière absolue: quand position
est réglé sur absolute
ou fixed
.
.bfc-root {
position: absolute;
}
Notez que ceux-ci peuvent avoir des effets collatéraux indésirables, comme l'écrêtage du contenu débordant, le calcul des largeurs automatiques avec l' algorithme de rétrécissement pour s'adapter ou devenir hors du flux. Le problème est donc qu'il n'est pas possible d'avoir un élément de niveau bloc en flux avec débordement visible qui établit un BFC.
L'affichage L3 résout ces problèmes:
Création des types d'affichage interneflow
et pour mieux exprimer les types d'affichage de disposition de flux et pour créer un commutateur explicite pour faire d'un élément une racine BFC . (Cela devrait éliminer le besoin de hacks comme et […])flow-root
::after { clear: both; }
overflow: hidden
Malheureusement, il n'y a pas encore de support de navigateur. Nous pourrons éventuellement utiliser
.bfc-root {
display: flow-root;
}