Les flottants (propriétés float et clear)
Généralités
Un élément flottant se place à la suite du flux, tout à gauche ou tout à droite de la ligne courante, selon qu'on lui ait attribué la valeur left ou right. Le flux principal poursuit sur le côté de la boîte flottante et ensuite au-dessous normalement.
Le contenu du flottant n'est pas pris en compte par un éventuel parent puisqu'il est dans un nouveau contexte de formatage et s'écoule en-dehors du flux principal.
Particularités d'un élément flottant
- Un élément flottant prent automatiquement un comportement "de type block" s'il était "de type inline" (inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block, inline-table->table) Il est donc inutile de spécifier un display:block à un span ou un lien que l'on fait flotter. De même, vouloir attribuer un display:inline-block à un élément que l'on fait flotter n'a aucun sens. Par contre, les autres type de display sont conservée, comme list-item, par exemple.
- Les marges d'un élément flottant ne fusionnent pas avec leur parent ni même entre 2 flottants positionnés l'un en-dessous de l'autre.
- Par défaut la largeur de l'élément s'adapte à son contenu, contrairement au comportement par défaut d'un type block qui occupe tout l'espace à disposition dans son conteneur.
La propriété clear
La propriété clear permet d'indiquer qu'un élément ne doit plus venir se positionner à côté des flottants et le force à venir se positionner au-dessous. On peut lui attribuer la valeurs:
- both se positionne en-dessous de tous les flottants
- left en dessous des flottants à gauche mais peut rester à côté d'un flottant à droite
- right en dessous des flottants à droite mais peut rester à côté d'un flottant à gauche.
Faire en sorte que le contenu adjacent au flottant ne passe pas dessous de celui-ci quand il est plus long
Il y a principalement 2 techniques pour le faire:
1) En laissant le texte dans le flux et en lui attribuant un margin (ou padding) correspondant au moins à la largeur du flottant
Cette méthode rencontre 2 inconvénients:
- L'apparition du bug des 3px sur IE6 et -
- La problématique d'un éventuel clear dans le texte qui agirait aussi sur le menu vu qu'on reste dans le flux principal
Cette option devrait donc être réservée au cas où seul le flottant à une dimension fixe et que le contenu adjacent peut avoir une taille variable. Par ailleurs pour régler le 2ème problème il est plus efficace d'utiliser une propriété créant un nouveau contexte de formatage sur le contenu adjacent. Ce qui a l'avantage de nous affranchir de toute déclaration de largeur ou marge dépendante de la largeur de l'élément flottant et donc de bénéficier d'une souplesse complète.
2) En positionnant aussi le texte en float.
De cette manière on évite l'apparition du bug des 3px et la problématique d'un l'éventuel clear dans le contenu adjacent vu que le flottement établit la création d'un nouveau contexte de formatage. Par contre, elle ne peut être utilisée que si l'on a une taille déterminée pour le contenu puisque le width devra être spécifié.
Faire en sorte que le parent prenne en compte les flottants pour déterminer sa hauteur
Comme le contenu du flottant s'écoule hors du flux principal, celui-ci n'est pas pris en compte par le parent pour déterminer sa hauteur. Cela peut poser problème dans le cas d'un élément ne contenant que des flottants et censé afficher une couleur de fond pour l'ensemble.
Voici 3 solutions:
1) Ajouter un élément vide après les flottant, dans le html, et lui attribuer la propriété clear
Cette solution était la plus utilisée au début des montages en css. On pouvait utiliser un div, un hr ou encore un br. Cependant elle n'est pas vraiment satisfaisante car on ajoute un élément vide dans le html qui n'a pas de sens sémantique.
2) utiliser la pseudo-classe :after
L'idée consiste à attribuer le clear au conteneur assigné à la pseudo-class :after. Cette méthode à le mérite de ne pas devoir intervenir dans le html.
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
Cependant internet explorer n'interprétant pas cette pseudo-class il faut aussi s'assurer que l'élément ait le layout.
3) Utiliser une propriété qui crée un nouveau contexte de formatage
Le plus simple est d'attribuer au parent l'une des propriétés qui créent un nouveau contexte de formatage. De cette manière le conteneur prendra bien en compte ses enfants flottants pour déterminer sa hauteur.
Si positionner le parent en float semble facile, cette propriété ne peut pas être employée dans tous les cas comme, par exemple, pour un élément centré ou pour un élément de largeur variable.
On utilise alors souvent la propriété overflow avec la valeur hidden (la valeur auto pouvant poser problème sur certains navigateurs) et on vérifie de donner le layout à l'élément pour IE6 (et versions précédentes) qui ne créent pas un nouveau contexte de formatage avec l'overflow: hidden (ok pour IE7) en rétablissant, si nécessaire l'overflow à visible pour eux.
Si cette solution n'est pas idéale puisqu'on utilise une propriété pour l'effet qu'elle induit et non pas pour sa raison d'être, elle a le mérite d'être simple.
Dans le futur
Dans le working draft de css3 de 2013, il est prévu éventuellement une propriété clear-after pour pallier à ce manque, mais elle est encore en dicussion et, à ma connaissance, pas encore implémentée.
Editer