Compartimentation CSS (CSS Containment)


L'objectif du module de spécification CSS Containment (pour Compartimentation CSS) consiste à améliorer les performances des pages web en permettant aux développeurs d'isoler un sous-ensemble de la page. Si le navigateur sait que cette partie est indépendante, le rendu peut être optimisé et les performances améliorées. Ce module de spécification définit une seule propriété CSS : contain. Dans cet article, nous verrons les objectifs principaux de cette spécification.

Exemple simple

De nombreuses pages web disposent de plusieurs sections qui sont indépendantes les unes des autres. Voici une liste d'articles avec leurs titres et leurs contenus.

<h1>Mon blog</h1>
<article>
  <h2>Titre d'un article sympa</h2>
  <p>Un peu de contenu.</p>
</article>
<article>
  <h2>Un autre titre pour un autre article</h2>
  <p>Un peu plus de contenu ici.</p>
</article>

Pour chaque article, on applique la propriété contain avec la valeur content.

article {
  contain: content;
}

Chaque article est indépendant des autres articles de la page et on fournit contain: content afin d'indiquer cette indépendance au navigateur. Ce dernier peut alors prendre des décisions quant au rendu du contenu (par exemple, ne pas travailler sur le rendu d'articles qui ne sont pas sur la zone visible).

Si on fournit contain: content pour chaque <article>, lorsque de nouveaux éléments sont insérés, le navigateur comprendra qu'il n'est pas nécessaire de tout repeindre/redisposer à l'intérieur de l'arbre de l'élément. Toutefois, si <article> est mis en forme de telle façon que sa forme dépend de son contenu (ex. height: auto), le navigateur devra prendre en compte le redimensionnement.

La valeur content est une valeur synthétique pour contain: layout paint. Elle indique au navigateur que la disposition de l'élément est complètement séparée de celle du reste de la page et que tout ce qui concerne l'élément est peint à l'intérieur de son cadre et que rien ne peut dépasser.

Cette information est parfois connue voire √©vidente pour la ou les personnes qui construisent la page. Toutefois, les navigateurs ne peuvent pas simplement deviner cette intention et partir du principe que chaque article ne d√©bordera pas. Cette propri√©t√© permet ainsi d'expliquer la situation au navigateur afin que celui-ci puisse en tirer parti et optimiser ce qu'il peut gr√Ęce √† cette hypoth√®se.

Concepts et terminologie

Cette spécification ne définit qu'une seule propriété : contain. Les valeurs fournies à cette propriété indiquent le type de compartimentation qu'on souhaite appliquer à l'élément.

Compartimentation de la disposition

article {
  contain: layout;
}

La disposition porte normalement sur l'int√©gralit√© d'un document et si on d√©place un √©l√©ment, c'est tout le document qui doit √™tre reconsid√©r√© car tout peut avoir boug√©. Avec contain: layout, on indique au navigateur qu'il est uniquement n√©cessaire de v√©rifier cet √©l√©ment et son contenu : tout ce qu'il contient n'affecte pas le reste de la page et la bo√ģte englobante cr√©e un contexte de formatage ind√©pendant.

De plus :

  • Les dispositions flottantes (avec display:float) seront trait√©es ind√©pendamment.
  • Les marges ne fusionneront pas en dehors des limites du bloc englobant ainsi compartiment√©
  • Le conteneur de la disposition sera un bloc englobant pour les √©l√©ments descendants avec des positions absolute/fixed.
  • La bo√ģte englobante cr√©e un contexte d'empilement et on peut donc utiliser z-index.

Compartimentation pour la peinture

article {
  contain: paint;
}

La compartimentation avec paint limite/rogne la bo√ģte jusqu'√† la limite de la zone de remplissage (padding) de la bo√ģte principale. Autrement dit, il ne peut pas y avoir de chevauchement visible. On a √©galement les m√™mes r√®gles qu'avec layout (voir ci-avant).

De plus, lorsque la bo√ģte englobante est hors de l'√©cran, le navigateur n'a pas besoin de peindre ses √©l√©ments (car ceux-ci sont contenus dans cette bo√ģte au sens g√©om√©trique).

Compartimentation pour le dimensionnement

article {
  contain: size;
}

La compartimentation du dimensionnement, utilis√©e seule, n'offre pas un grand int√©r√™t quant aux performances. Cette valeur signifie que la taille des √©l√©ments fils ne doit pas affecter la taille de l'√©l√©ment cibl√© ‚ÄĒ sa taille est calcul√©e comme si l'√©l√©ment n'avait pas de fils.

Si on active contain: size, il faut alors définir la taille de l'élément sur lequel on l'applique. Sinon, dans la plupart des cas, l'élément aura des dimensions nulles.

Compartimentation pour le style

article {
  contain: style;
}

Malgré son nom, cette valeur ne fournit pas un style compartimenté comme on pourrait l'avoir avec un Shadow DOM. Cette valeur sert principlament pour les compteurs CSS qui pourraient changer sur un élément et affecter le reste de l'arborescence.

En utilisant contain: style, on s'assure que les propriétés counter-increment et counter-set créent de nouveaux compteurs limités à ce sous-arbre.

Note : La valeur style est consid√©r√©e comme ¬ę √† risque ¬Ľ dans la sp√©cification actuelle et pourrait ne pas √™tre prise en charge partout (elle n'est actuellement pas prise en charge dans Firefox - novembre 2019).

Valeurs spéciales

La propriété contain possède deux valeurs spéciales :

  • content
  • strict

La premi√®re (vue dans le premier exemple) est un synonyme pour la conjonction de layout et paint. La sp√©cification d√©crit cette valeur comme pouvant ¬ę raisonnablement √™tre appliqu√©e largement de fa√ßon saine ¬Ľ. Elle n'applique pas la compartimentation pour le dimensionnement (size) donc on ne risque pas d'avoir une bo√ģte avec une taille nulle en raison de la taille de ses enfants.

Pour obtenir la compartimentation la plus forte, on utilisera contain: strict qui est synonyme de contain: size layout paint voire on ajoutera ensuite la compartimentation du style pour les navigateurs qui la prennent en charge :

contain: strict;
contain: strict style;

Référence

Propriétés CSS

Ressources externes