Certaines spécifications CSS sont plus obscures que d'autres. Mais il est du devoir d'un intégrateur de les connaître pour être plus efficace dans son métier.
Qui n'a jamais pesté contre des éléments flottants qui ne se comportent pas comme espéré ?
Qui n'a pas été une fois au-moins dérouté par des marges verticales venues de nulle part ?
Ces comportements, comme d'autres, sont décrits et expliqués au sein d'une spécification concernant le “Visual Formatting Model”, qui décrit globalement le concept de flux d’affichage, de boîtes et de modes de rendu visuel.
Voyons comment déchiffrer cette ressource cruciale…
Block et Inline sont sur un bateau (qui float)
Pour commencer, la spécification chamboule nos croyances établies et nous apprend à distinguer les blocks… des blocks.
Si vous pensiez qu’un élément block est simplement un élément qui possède la règle display: block
, eh bien en fait, non, c’est un peu plus subtil que ça
-
Les éléments “block” (block level) sont ceux affectés par :
display: block
, mais aussidisplay: list-item
, etdisplay: table
ils s’inscrivent dans un contexte de formatage block. -
Les éléments “inline” (inline level) sont ceux affectés par :
display : inline
, mais aussidisplay: inline-table
, etdisplay: inline-block
ils s’inscrivent dans un contexte de formatage inline. - Note : CSS3 étend ces valeurs, mais on ne va pas se compliquer la vie inutilement ici.
Mais c’est quoi un “contexte de formatage block” ?
La spécification précise que certains éléments créent un “contexte d’affichage” pour les enfants qu’ils contiennent.
Ce contexte peut être de type “block” (les enfants - quels qu’ils soient - de ce contexte s’affichent les uns sous les autres) ou de type “inline” (les enfants s’affichent les uns à côté des autres).
Pour générer ce fameux “contexte de formatage “block””, le conteneur doit bénéficier de l’une des règles suivantes :
-
float: left
oufloat: right
-
position : absolute
-
position : fixed
(ajouté dans les specs CSS3) -
display : inline-block
-
display : table-cell
-
display : table-caption
-
display : table
(indirectement via création d’un élément anonyme table-cell) -
overflow : hidden
-
overflow : scroll
-
overflow : auto
Note importante : vous aurez remarqué qu'un élément en display: block
ne crée pas de “contexte de formatage block”.
Des sortes de “super éléments” ?
Les éléments générant un contexte de formatage block deviennent des sortes de “super éléments” ayant un certain nombre de super responsabilités : ils deviennent entre-autre garants de l’affichage de leurs enfants (qu’ils soient blocks ou inline).
Ces super éléments acquièrent également des super pouvoirs très pratiques, et c'est là que ça devient intéressant :
- Ils contiennent des flottants
- Ils ne s’écoulent pas autour des flottants
- Ils ne subissent pas la fusion de marges
- Et plein d’autres petites fioritures
En passant, on pourrait comparer ces super-pouvoirs à ceux propriétaires de Microsoft par le HasLayout d’Internet Explorer (on pense au désormais célèbre zoom: 1).
Démonstrations en image…
1- Débordement de flottants :
Des éléments flottants, hors du flux, "débordent" généralement de leur parent, c'est normal :
Par contre, lorsque ce parent dispose d'un contexte de formatage, il est capable de "contenir les blocs" descendants :
2- Ecoulement autour d’un flottant :
Le contenu qui suit un élément flottant s'écoule naturellement autour de ce flottant :
Si ce contenu bénéficie d'un contexte de block, il ne s'écoule plus et reste calé à droite du flottant :
3- Fusion de marges :
Les marges verticales des enfants se répercutent sur leurs parents, c'est la fusion de marges (ici le margin-top de l'enfant ne s'applique pas sur l'enfant mais sur son parent) :
La fusion de marge n'a pas d'effet sur un éléments de "contexte block". Ainsi, dans cette seconde illustration ci-dessous, margin-top
s'applique sur l'élément et non pas sur son parent :
Besoin d'un visuel pour mieux comprendre ?
Vous trouverez une compilation de tests de techniques de BFC sur la page dédiée suivante :
Commentaires
Ca vaut de l'or cette petite mise au point ! Merci !
@laudag : Merci à toi ! :)
C'est vrai que c'est très intéressant comme article, et de surcroit en français ;)
mais bon j'ai parfois l'impression que c'est un brin compliqué pour ce que l'on cherche a faire non ? et parfois pas naturel; par exemple, un overflow:hidden permettrais donc de contenir ses enfants, alors que son but initial est de cacher ce qui dépasse ... ?
+1 laudag ce genre d'explication ( de surcroit en français ) vaut de l'or !
Et sinon histoire de ne pas être trop jovial, disons que je suis un peu triste de ne pas avoir eu cet article dans le bouquin Css avancées de Raphaël, d'autant plus qu'un partie y ressemble, avec l'utilisation d'une bordure transparente contre la fusion des marges cet ...
Et moi qui me casse la tête sur de "petites choses", alors là...
Mais c'est toujours un plaisir de lire vos articles et de tester, enfin j'essaye, je suis patient ;-)
@themagicdavid: overflow: auto; marchera très bien aussi. ;)
Pour l'anecdote du "comportement inattendu" des blocks, je penses que tout développeur web est passé par la à un moment donné. J'ai bien aimé l'approche de l'auteur consistant à tester les différents scénarios pour bien cerner l'intérêt et les limites de chaque configurations. C'est simple et ça parle, bon post
Je cherchais justement un tableau de rappel. À bookmarker de suite.
Merci pour cet article.
@Manumanu j'ai bien compris la possibilité, je disais simplement que ça me semblais pas cohérent avec sa fonction première :)
Merci pour ce petit (et nécessaire) rappel, d'autant plus que l'article de Laurent (sur son ancien blog) n'est en ligne.
Concernant la boîtes de block, Hakon Lie l'avait définie comme « A box generated by a block-level element, which has a line break before and after itself »
A titre perso je n'utilise que du float, l'élément s'adapte au contenu si on ne lui donne aucune taille dans le cas contraire il prendra la taille qu'on lui attribut.
Pour faire des site "Responsive" le placement en float c'est magique!
Il suffit de bien mettre un clear a chaque fois qu'on veux aller à ligne.
Si on couple ca avec un bon reset.css tous les navigateurs et même IE seront d'accord.
Mais si je n'y arrive pas tous le temps un site bien intégré et un site qui n'a qu'une seul feuille de style pour tous les navigateurs, mais bon c'est pas toujours possible....
Merci pour vos retours.
@themagicdavid : "disons que je suis un peu triste de ne pas avoir eu cet article dans le bouquin Css avancées de Raphaël"
-> Je te promets que si j'avais compris ce modèle aussi bien qu'aujourd'hui, ces explications auraient été précisées dans le livre ! :)
Le plus déroutant (le plus idiot en fait) me semble être la fusion des marges dont je doute de l'utilité...
Mais merci pour l'info
Merci pour ce tuto Raphaël. C'est très clair sauf que dans mes essais http://codepen.io/franck/pen/BGeKE, au niveau... de " l'écoulement autour d'un flottant", j'ai un pb de calage à droite. Seuls "display:inline-block" ET une largeur aux éléments fonctionne. Si je mets du overflow ou position, ça ne marche plus
Quelqu'un peut me dire ce que j'oublie ?
@franckichmish : évidement, le lien c'est ça http://codepen.io/franck/pen/BGeKE
Merci de lever un voile sur une part de la sorcellerie des CSS ! ;-) C'est un vrai travail de médecin pour toutes les petites plaies des intégrateurs !
@themagicdavid : moi aussi je viens de découvrir depuis peut la fonction contenante de overflow:hidden...
Je suis un débutant en css et html.et vos tutos m'aide beaucoup.merci MR RAPHAEL