CSS Float : élément html flottant et gestion du flux

Introduction

La propriété css float:left; est certainement l’une des règles les plus déstabilisantes lorsque l’on découvre le css et que l’on veut intégrer un design en html css :

  • elle est essentielle car elle permet de positionner facilement des éléments html les uns à côté des autres et ainsi créer des colonnes
  • elle impacte le comportement de son parent dans son calcul de sa hauteur et de sa largeur : le parent ne les prends pas en compte ses dimensions ainsi que ses bordures / margin / padding
  • les bloc du design vont alors mal se positionner : ils sont se mettre à la suite les uns des autres et/ou se mettre en dessous d’un élément qui est plus petit qu’un autre (problème typique lorsque l’on crée une page avec une grille de produit où les titres et les descriptions ont des nombres de caractères variables)

Voici deux exemples typiques :

Problème de flux : Les éléments en block sont mis à la suite et se chevauchent

Problème de flux : Les éléments en block sont mis à la suite et se chevauchent

Problème de flux : l'image chevauche plusieurs paragraphes

Problème de flux : l’image chevauche plusieurs paragraphes

Cet article présente en détail le concept de flux html et donne plusieurs solutions pour rétablir le flux de l’élément parent lorsque l’on utilise des éléments flottants.

Le concept de flux

  • un élément en block a, part défaut, la largeur de son contenant et la hauteur de son contenu
  • un élément en ligne a, part défaut, la largeur et la hauteur de son contenu
  • un élément en block, qui contient des éléments en bloc ou en ligne, a part défaut, la largeur de son contenant et la hauteur de son contenu (donc ce bloc aura pour hauteur la somme des hauteurs des éléments en bloc ou en ligne imbriqués à l’intérieur)

Le concept de flux avec float

si un élément html possède la propriété float:left;, il est dit flottant.
Lorsqu’un élément est flottant, il a un comportement particulier en terme de positionnement :

  • il va se positionner le plus à gauche et le plus en haut de la balise le contenant
  • la balise contenant le ou les éléments flottant, aussi appelé conteneur ou balise parent, ne le prend pas en compte pour calculer sa longueur et sa hauteur. Si le conteneur ne dispose que d’éléments flottant sa hauteur est nulle

Float sur les éléments en ligne et les éléments en block

  • si on utilise la propriété float:left; sur un élément en block comme <li> + préciser une width:value[px,em,rem,%]; les éléments vont se mettre à la suite pour former des colonnes
  • Float Element flottant de type block avec flux rétabli au niveau des parents

    Element flottant de type block avec flux rétabli au niveau des parents

  • si on utilise la propriété float:left; sur un élément en ligne comme <img>, l’élément dispose de la propriété display:inline-block;. Les autres éléments en ligne vont se mettre à la suite: technique très utilisée pour ajouter une image dans une zone de texte
  • Element flottant de type enligne sur une image pour faire une lettrine

    Element flottant de type enligne sur une image (pour faire une lettrine) avec flux rétabli au niveau des parents

Rétablir le flux – solution via une balise comme dernier enfant du conteneur + du css sur cette balise

La première solution pour rétablir le comportement par défaut du bloc parent pour le calcul de sa hauteur et sa largeur est de créer une règle css .clear avec le code ci dessous et d’ajouter à chaque conteneur une balise html comme dernier enfant. La balise peut être une div, br.

<!DOCTYPE html>
<html lang="fr">
<head>
	<meta charset="UTF-8">
	<title>Solution 1 - retour du flux</title>
	<style>

	#conteneur{
		border : 1px solid blue;
	}
	.clear {
		content :" "; // facultatif si ajout d'un espace avec &nbsp; dans le html
		height:0; // uniquement pour la mise en forme
		visibility: hidden; // uniquement pour la mise en forme
		clear:both; // obligatoire
		display: block; // facultatif si utilisation de div dans le html
	}

	p {
		width:50%;
		float:left;
		box-sizing: border-box;
		border:1px solid red
	}
</style>
</head>
<body>
	<div id="conteneur">
		<p>lorem</p>
		<p>ipsum</p>
		<br class="clear">
	</div>
</body>
</html>

Rétablir le flux – solution via du css sur le conteneur avec le pseudo sélecteur :after

La deuxième solution pour rétablir le comportement par défaut du bloc parent pour le calcul de sa hauteur et sa largeur est d’ajouter un dernier enfant au conteneur grâce à la combinaison du pseudo sélecteur :after et de la propriété content :" ";.
Cette solution est disponible dans le Twitter Bootstrap sous la class helper clearfix

<!DOCTYPE html>
<html lang="fr">
  <head>
    <meta charset="UTF-8">
    <title>Solution 2 - retour du flux</title>
    <style>
      #conteneur{
        border : 1px solid blue;
      }
      #conteneur:after {
        content :" "; // obligatoire
        height:0; // uniquement pour la mise en forme
        visibility: hidden; // uniquement pour la mise en forme
        clear:both; // obligatoire
        display: block; // obligatoire
      }
      p {
        width:50%;
        float:left;
        box-sizing: border-box;
        border:1px solid red
      }
    </style>
  </head>
  <body>
    <div id="conteneur">
     <p>lorem</p>
     <p>ipsum</p>
    </div>
  </body>
</html>

Rétablir le flux – solution via du css sur le conteneur

La troisième solution pour rétablir le flux du conteneur est de lui ajouter la propriété css overflow : hidden;

<!DOCTYPE html>
<html lang="fr">
<head>
	<meta charset="UTF-8">
	<title>Solution 3 - retour du flux</title>
	<style>
	#conteneur {
		overflow : hidden; // obligatoire
		zoom : 1;/*pour IE < 8 */
		border : 1px solid blue;
	}

	p {
		width:50%;
		float:left;
		box-sizing: border-box;
		border:1px solid red
	}
</style>
</head>
<body>
	<div id="conteneur">
		<p>lorem</p>
		<p>ipsum</p>
	</div>
</body>
</html>

la nouvelle solution : la propriété display: flex sur le conteneur

La dernière solution est de ne pas utiliser float:left au niveau des enfants, mais d’utiliser display: flex; au niveau du conteneur

<!DOCTYPE html>
<html lang="fr">
<head>
	<meta charset="UTF-8">
	<title>Solution 4 - display flex</title>
	<style>
	#conteneur {
		border : 1px solid blue;
		display: flex; // obligatoire
	}

	p {
		width: 50%;
		box-sizing: border-box;
		border:1px solid red
	}
</style>
</head>
<body>
	<div id="conteneur">
		<p>lorem</p>
		<p>ipsum</p>
	</div>
</body>
</html>

cas où la propriété float est ignorée

La propriété float est ignorée si on utilise sur le même élément display:none; ou position:absolute;.
Le fait d’utiliser simultanément l’une de ces propriétés avec float va l’annuler.