web-dev-qa-db-fra.com

Éléments flottants dans une div, flotte en dehors de div. Pourquoi?

Supposons que vous ayez un div, que vous le coloriez en vert et que vous lui donniez une largeur définie, lorsque j'y mets des éléments, dans mon cas, un img et un autre div. L'idée est que le contenu de la div de conteneur entraînera une extension de la div de conteneur et constituera un arrière-plan pour le contenu. Mais lorsque je le fais, le div contenant se rétrécit pour s'adapter aux objets non-flottants, et les objets flottants seront soit complètement sortis, soit à moitié sortis, à moitié entrés, et n'auront aucune incidence sur la taille du grand div.

Pourquoi est-ce? Y-a-t-il quelque chose qui me manque et comment puis-je obtenir des objets flottants pour étendre la hauteur d'un div conteneur?

249
DavidR

Le plus simple est de mettre overflow:hidden sur le div parent et de ne pas spécifier de hauteur:

#parent { overflow: hidden }

Une autre façon est de faire flotter le div parent:

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

Une autre manière utilise un élément clair:

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

CSS

span.clear { clear: left; display: block; }
371
Doug Neiner

Raison

Le problème est que les éléments flottants sont hors flux :

Un élément est appelé hors du flux s'il est flottant, absolument positionné ou s'il est l'élément racine.

Par conséquent, ils n’ont pas d’impact sur les éléments environnants comme le ferait un élément in-flow .

Ceci est expliqué dans 9.5 Floats :

Puisqu'un flottant n'est pas dans le flux, les blocs non positionnés créés avant et après le flottant s'écoulent verticalement comme si le flottant n'existait pas. Toutefois, les zones de ligne actuelles et suivantes créées à côté du float sont raccourcies si nécessaire pour laisser de la place à la zone de marge du float.

enter image description here

_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 blocs "normaux" ,

Seuls les enfants du flux normal sont pris en compte (c'est-à-dire que les boîtes flottantes et les boîtes en position absolue sont ignorées […])

enter image description here

_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: clairance

Une façon de résoudre le problème consiste à forcer un élément entrant dans le flux à être placé 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 propriété clear :

Cette propriété indique quels côtés de la (des) zone (s) d'un élément peuvent ne pas être adjacents à une boîte flottante antérieure.

enter image description here

_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 ajoute un élément vide avec _clear: both_ comme dernier frère des floats

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

Cependant, ce n'est pas sémantique. Il est donc préférable de 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 à deux points obsolète _:after_ pour prendre en charge les anciens navigateurs, ou en utilisant d'autres affichages niveau bloc comme _display: table_.

Solution: racines de 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 de BFC), il enveloppera également son contenu flottant.

Selon 10.6.7 hauteurs 'Auto' pour les racines de contexte de formatage de bloc ,

Si l'élément a des descendants flottants dont la marge inférieure est inférieure à la limite inférieure du contenu de l'élément, la hauteur est augmentée pour inclure ces bords.

enter image description here

_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é 9.5 Floats , les racines BFC sont également utiles pour les raisons suivantes:

La zone de bordure d'un tableau, un élément remplacé au niveau du bloc ou un élément du flux normal qui établit un nouveau contexte de formatage de bloc […] ne doit pas chevaucher la zone de marge de tout élément flottant dans le même contexte de formatage de bloc que l'élément lui-même. .

enter image description here

_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

  • Blocs avec overflow autre que visible, par ex. hidden

    _.bfc-root {
      overflow: hidden;
      /* display: block; */
    }
    _
  • Bloquez les conteneurs qui ne sont pas des boîtes de bloc: quand display est défini sur _inline-block_, _table-cell_ ou _table-caption_.

    _.bfc-root {
      display: inline-block;
    }
    _
  • Éléments flottants: lorsque float est défini sur left ou right.

    _.bfc-root {
      float: left;
    }
    _
  • Éléments positionnés de manière absolue: quand position est défini sur absolute ou fixed.

    _.bfc-root {
      position: absolute;
    }
    _

Notez que ceux-ci peuvent avoir des effets collatéraux indésirables, tels que le débordement du contenu saturé, le calcul des largeurs automatiques avec l'algorithme shrink-to-fit ou la perte de contrôle. Le problème est donc qu'il n'est pas possible d'avoir un élément de niveau bloc dans le flux avec un dépassement de capacité visible qui établit un BFC.

Display L résout ces problèmes:

Créé le flow et flow-roottypes d'affichage interne pour mieux exprimer la disposition des flux types d'affichage et créer un commutateur explicite pour rendre un élément a BFC root. (Cela devrait éliminer le besoin de piratages tels que _::after { clear: both; }_ et overflow: hidden […])

Malheureusement, il n'y a pas encore de support pour le navigateur. Finalement, nous pourrons peut-être utiliser

_.bfc-root {
  display: flow-root;
}
_
143
Oriol

Mettez votre div(s) flottante dans une div et donnez-la en CSS overflow:hidden;
Cela fonctionnera bien.

19
Nad

Recommandation de W3Schools:

mettez overflow: auto sur l'élément parent et "colorera" tout l'arrière-plan, y compris les marges des éléments. De plus, les éléments flottants resteront à l'intérieur de la frontière.

http://www.w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix

13
mggluscevic

Il ne manque rien Flottante a été conçue pour le cas où vous souhaitez qu'une image (par exemple) soit placée à côté de plusieurs paragraphes de texte, de sorte que le texte circule autour de l'image. Cela ne se produirait pas si le texte "étirait" le conteneur. Votre premier paragraphe se terminerait et votre prochain paragraphe commencerait sous l'image (éventuellement plusieurs centaines de pixels en dessous).

Et c'est pourquoi vous obtenez le résultat que vous êtes.

11

Dans certains cas, c'est-à-dire when (if) vous utilisez simplement float pour que les éléments circulent sur la même "ligne", vous pouvez utiliser

display: inline-block;

au lieu de

float: left;

Sinon, utiliser un élément clear à la fin fonctionne, même si cela peut aller à contre sens de nécessiter un élément pour faire ce qui devrait être du travail CSS.

9
LSerni

Voici une approche plus moderne:

.parent {display: flow-root;} 

Plus de correctifs.

p.s. Utilisation du débordement: caché; cache la boîte-ombre alors ...

7
pendingfox

Merci LSerni vous l'avez résolu pour moi.

Pour y parvenir:

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

Tu dois faire ca :

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

Comme Lucas l'a dit, vous décrivez le comportement prévu pour la propriété float. Ce qui déroute beaucoup de gens, c'est que float a été poussé bien au-delà de son utilisation initiale afin de compenser les lacunes du modèle de mise en page CSS.

Jetez un œil à Floatutorial si vous souhaitez mieux comprendre le fonctionnement de cette propriété.

4
Sam Murray-Sutton