Le contexte de formatage block en CSS

Astuce par (Intégrateur du Dimanche, Strasbourg)
Créé le , mis à jour le (28438 lectures)
Tags : float, fusion des marges, débordement, clearfix, clear, BFC, formattage

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 aussi display: list-item, et display: table
    ils s’inscrivent dans un contexte de formatage block.
  • Les éléments “inline” (inline level) sont ceux affectés par : display : inline, mais aussi display: inline-table, et display: 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 ou float: 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 :

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 :

Voir la démo

Ressources sur ce sujet :

Commentaires

laudag a dit le

Ca vaut de l'or cette petite mise au point ! Merci !

Raphael a dit le

@laudag : Merci à toi ! :)

themagicdavid a dit le

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 ...

Auguste a dit le

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 ;-)

Manumanu a dit le

@themagicdavid: overflow: auto; marchera très bien aussi. ;)

vtcreative a dit le

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

gfiche a dit le

Je cherchais justement un tableau de rappel. À bookmarker de suite.
Merci pour cet article.

themagicdavid a dit le

@Manumanu j'ai bien compris la possibilité, je disais simplement que ça me semblais pas cohérent avec sa fonction première :)

Hermann a dit le

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 »

AzRaElDGT a dit le

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....

Raphael a dit le

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 ! :)

dreadcast a dit le

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

franckichmish a dit le

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 a dit le

@franckichmish : évidement, le lien c'est ça http://codepen.io/franck/pen/BGeKE

Jordi a dit le

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 !

Olivier C a dit le

@themagicdavid : moi aussi je viens de découvrir depuis peut la fonction contenante de overflow:hidden...

dioulde77 a dit le

Je suis un débutant en css et html.et vos tutos m'aide beaucoup.merci MR RAPHAEL