Toute la clarté sur les clearfix css

Attention:  cet article date du 9 novembre 2012
Ce qu'il contient est peut être encore valable...
... ou complètement obsolète!

Il est des situations où, dans tout langage, on est amené à bidouiller. Le html et ses CSS ne faisant pas exception à la règle (voire en sont souvent de gros consommateurs).

Sujet du jour: les clear-fix, ou comment rattraper un fond perdu

Pourquoi ?

La situation de départ est un grand classique: une div qui en contient deux, l’une qui float à gauche, l’autre à droite (ou les deux à gauche… ou les deux à droite…).

Une sorte de site en deux colonnes.

Si l’on se contente de faire flotter les deux colonnes, nous ne voyons pas le joli fond gris du conteneur, et sa belle bordure noire est un peu tassée en haut.

Pourquoi? Tout simplement puisque cette div ne contient que des éléments qui flottent, elle ne contient en fait rien du tout.

Et comme toute div qui se respecte, si elle est vide, elle n’a pas de hauteur, donc pas de background et une bordure minimum.

Height, height, non !

Puisqu’elle n’a pas de hauteur, une solution qui vient à l’esprit est de lui fixer une hauteur

Cette solution est bonne, sauf que trouver la bonne hauteur est parfois un casse-tête. Sur l’exemple ci dessus j’ai (volontairement) mis une hauteur arbitraire, mais qui ne colle pas.

Quelle hauteur prendre ? Généralement celle du plus grand. Sauf que l’on ne connait pas forcément la hauteur du plus grand. A fortiori dans un site dynamique ou le contenu peut changer à n’importe quel moment, et donc les hauteurs.

Cette solution n’est à retenir que si vous maitrisez parfaitement le contenu de la div à problème, et donc sa hauteur (un menu de navigation par exemple…).

Et encore…

J’ai souvenir (mais la flemme de chercher) d’un bout de JavaScript qui permettait de mesurer les hauteurs des deux divs flottantes, et de pouvoir ainsi ajuster dynamiquement la hauteur de la div conteneur. Solution intéressante, mais finalement il y a plus simple et plus clair…

La class clear, c’est clair ?

La plupart des intégrateurs vont ajouter juste avant la fermeture de la div contenteneur une balise possédant une class spécifique, généralement appelée clear car elle sert à appliquer une règle css. Et à fixer les flottants, donc clear-fix (même si le nom n’est pas important)

En version de base ceci:

.clear {
   clear: both;
}

Le html sera alors:

<div class="content">
   <div class="gauche">...</div>
   <div class="droite">...</div>
   <XXX class="clear"></XXX>
</div>

Dont le résultat est celui que l’on cherche (bordure autour, fond gris)

Là où il peut y avoir débat (ou matière à discution, disons) c’est sur la structure html.

Là où j’ai mis XXX… Bref, sur quelle balise l’appliquer?

Un séparateur horizontal <hr>

A mon sens, le <hr> ayant un rôle de ligne de séparation il n’est pas absurde de l’utiliser à cette fin (personnellement, il ne me sert d’ailleurs rarement à autre chose).

Et parfois même sans classe (puisqu’il ne me sert qu’à ça…)

<div class="content">
   <div class="gauche"></div>
   <div class="droite"></div>
   <hr />
</div>

On rajoutera alors un peu de css pour le rendre non visible (mais pas en display:none sinon le clear ne s’effectue pas), avec une hauteur minimum…

hr {
   clear: both;
   visibility: hidden;
   border: 0; margin: 0; overflow: hidden; height: 0;
}

On remarque qu’il y a beaucoup de bla bla, permettant de s’assurer de la disparition totale du <hr> (à réduire si vous utilisez un css reset…)

Conservez la classe si vous utilisez les <hr> à d’autres fins…

Une division <div>

Je préfère utiliser <hr> mais il est vrai que l’on trouve (très) souvent une

<div class="clear"></div>

En retenant le principe qu’une <div> correspond à une division.

div.clear {
    clear: both;
}

Moins de bla bla dans la css, mais plus dans la partie html, puisqu’il faut (obligatoirement) ajouter une classe… et fermer la </div>.

Sans compter que les chipoteurs vous diront qu’une balise <div> est un conteneur, et s’il est vide ce n’est pas sémantiquement correct. Certains ajouteront alors un &nbsp; à l’intérieur, mais devront jongler pour le cacher (comme pour le <hr>).

Un retour à la ligne, <br>

D’autres partent du principe qu’utiliser un <br> n’est pas absurde. Cela se tient, puisque son rôle est de permettre un retour à la ligne.

Dans les versions anciennes du html, il possédait un attribut clear, aujourd’hui déprécié. Qui donnait ceci (à ne plus utiliser):

<br clear="left"> <!-- obsolète -->

En version CSS, cela nous donne:

br.clear {
   clear: both; margin: 0; padding: 0; border: 0; 
   height: 0; line-height: 1px; font-size: 1px; 
}

Là encore, pas mal de bla bla aussi, proche de celui du <hr> ci dessus.

Les mêmes chipoteurs vous diront que si le W3C a déprécié l’usage du clear…  Oui, mais non. Le W3C à déprécié l’attribut html clear et conseille d’appliquer une CSS…

J’ai cependant une certaine allergie personnelle à l’utilisation du <br>.

Dans tous les cas, libre à vous d’utiliser l’une ou l’autre de ces balises, tant qu’elle est bien définie dans la css et correctement appliquée partout dans le html.

Et attention, note à certains de mes élèves, à ne pas utiliser un id=clear car cela limiterait à un seul clear par page. Et même si vous n’en avez ponctuellement qu’un seul, cela peut changer: créez une classe tout de suite…

NOTE: vous avez remarqué, la capture écran est la même partout. C’est logique, le résultat aussi… On la reverra d’ailleurs encore une fois, un peu plus bas…

Before / after…

Celui là, je ne l’ai pas inventé (les autres non plus, il est vrai). Il est moins spontané:

.content:before, .content:after {
    content: " ";
    display: table;
}
.content:after {
    clear: both;
}
.content { *zoom: 1; }

La dernière ligne servant à assurer une compatibilité avec de vieux navigateurs…

Quand à la structure html:

<div class="content">
   <div class="gauche"></div>
   <div class="droite"></div>
</div>

Là, pour le coup, il n’y a pas de bla bla, puisque rien à ajouter dans la <div> conteneur…

Toutes les explications sur le blog de Nicolas Gallagher qui à défaut d’en être l’inventeur semble l’avoir amélioré.

<div id= »article » class= »clear« >ceci est la fin de l’article…</div>

Laisser une réponse