Spécifications CSS
6 L'assignation des valeurs des propriétés, la cascade et l'héritage
Contenu
6.1 Les valeurs spécifiées, calculées et réelles
Une fois qu'un agent utilisateur a parcouru un document et en a construit un arbre, celui-ci, pour chacun des éléments de l'arbre, doit attribuer une valeur pour chacune des propriétés concernées par le type de média visé.
La valeur finale d'une propriété est le résultat d'un calcul en trois étapes : celle-ci est déterminée par la spécification (la valeur "spécifiée"), puis, si nécessaire, calculée en valeur absolue (la valeur "calculée") et finalement transformée en accord avec les contraintes de son contexte (la valeur "réelle").
6.1.1 Les valeurs spécifiées
Les agents utilisateurs doivent d'abord appliquer une valeur spécifiée à une propriété selon le mécanisme suivant (dans l'ordre de priorité) :
- Si la cascade donne une valeur, utiliser celle-ci ;
- Sinon, si la propriété est héritée, utiliser la valeur de l'élément parent, qui est en général une valeur calculée ;
- Sinon, utiliser la valeur initiale de la propriété. Cette valeur initiale est définie pour chaque propriété.
La racine de l'arbre du document n'ayant pas de parent, et ne pouvant donc pas hériter de valeurs, c'est la valeur initiale qui est utilisée si nécessaire.
6.1.2 Les valeurs calculées
Les valeurs spécifiées peuvent être absolues (ex. les valeurs 'red' et '2mm' ne sont pas relatives à une autre valeur) ou relatives (ex. les valeurs 'auto', '2em' et '12%' se rapportent à une autre valeur). Une valeur absolue ne requiert aucune opération supplémentaire pour établir sa valeur calculée.
Par contre, une valeur relative doit subir une transformation qui aboutit à sa valeur calculée : une valeur en pourcentage doit être multipliée par une valeur de référence (celle-ci est précisée pour chaque propriété), une valeur avec une unité relative (em, ex, px) devra devenir absolue par multiplication avec les tailles de police ou de pixel appropriées, les valeurs 'auto' doivent être calculée selon les formules données pour chaque propriété, certains mots-clés ('smaller', 'bolder', 'inherit') doivent être remplacés en accord avec leurs définitions.
Dans la plupart des cas, les éléments héritent de valeurs calculées. Cependant, certaines propriétés ont des valeurs spécifiées qui sont héritées (ex. la valeur numérique de la propriété 'line-height'). Dans les cas où les éléments enfants n'héritent pas de valeurs calculées, ceci est décrit dans les définitions des propriétés.
6.1.3 Les valeurs réelles
Bien qu'une valeur calculée soit en principe prête à l'emploi, un agent utilisateur peut ne pas pouvoir l'utiliser dans un environnement donné. Par exemple, celui-ci ne peut rendre les épaisseurs des bordures qu'avec un nombre entier de pixels, en conséquence, il lui faudra peut-être effectuer une approximation. La valeur réelle est égale à la valeur calculée après approximation éventuelle.
6.2 L'héritage
Les éléments enfants héritent de certaines valeurs de leurs éléments parents dans l'arbre du document. Chacune des propriété définit si elle est héritée, ou non.
Supposons un élément accentué (ici EM) dans un élément H1 :
<H1>Le titre <EM>est</EM> important !</H1>
Si aucune couleur n'est précisée pour l'élément EM, le mot accentué "est" héritera de la couleur de l'élément parent, ainsi, si l'élément H1 a une couleur bleu, EM le sera également.
Pour appliquer une propriété de style "par défaut" à un document, un auteur peut l'appliquer à la racine de l'arbre du document. Par exemple en HTML, on peut utiliser les éléments HTML ou BODY pour cet usage. Noter que ceci fonctionnera même si on omet la balise BODY dans la source HTML, l'interpréteur HTML inférant la balise manquante.
Par exemple ici, tous les descendants de l'élément BODY auront la valeur de couleur 'black', la propriété 'color' étant héritée :
BODY { color: black; }
Les valeurs de pourcentage spécifiées ne sont pas héritées, celles calculées le sont.
Par exemple, cette feuille de style :
BODY { font-size: 10pt } H1 { font-size: 120% }
et cet extrait d'un document :
<BODY> <H1>Un <EM>grand</EM> titre</H1> </BODY>
Ici, la propriété 'font-size' de l'élément H1 aura une valeur calculée de '12pt' (120% de la valeur de son parent). Et, comme la valeur de la propriété 'font-size' est héritée, la valeur calculée pour l'élément EM sera aussi '12pt'. Si l'agent utilisateur ne dispose pas d'une police de 12 pt mais, par exemple, d'une police de 11 pt, la valeur réelle de la propriété 'font-size' de ces éléments pourrait être '11pt'.
6.2.1 La valeur 'inherit'
On peut spécifier pour chacune des propriétés la valeur 'inherit', ce qui signifie, pour un élément donné, que la propriété de cet élément prend la même valeur calculée que pour celle de son parent. La valeur héritée qui est normalement utilisée comme une valeur refuge, peut être renforcée par une valeur 'inherit' explicite.
La valeur 'inherit' provoque l'héritage des valeurs par les propriétés. Ceci s'applique également aux propriétés dont la valeur n'est normalement pas héritée.
Dans l'exemple ci-dessous, on applique les propriétés 'color' et 'background' à l'élément BODY. La valeur de 'color' sera héritée par tous ses éléments et leur fond sera transparent. Si ces règles font partie de la feuille de style de l'utilisateur, un texte en noir sur fond blanc sera respecté dans tout le document.
BODY { color: black !important; background: white !important; } * { color: inherit !important; background: transparent; }
6.3 La règle @import
La règle '@import' permet aux utilisateurs l'importation de règles de style à partir d'une autre feuille de style. Les règles @import doivent précéder toutes autres règles dans la feuille de style. Le mot-clé '@import' doit être suivi de l'adresse URI de la feuille de style à intégrer. On admet aussi la forme avec une chaîne de caractères, celle-ci sera considérée comme étant enserrée dans url(...).
Les lignes suivantes ont une signification équivalente et illustrent les deux syntaxes (celle avec "url()" et celle avec une simple chaîne) :
@import "mystyle.css"; @import url("mystyle.css");
Comme les agents utilisateurs ne sont pas tenus de rassembler les ressources pour des types de média inconnus d'eux, les auteurs peuvent spécifier des règles @import selon les médias requis. Les imports conditionnels précisent leurs types, séparés par des virgules après l'adresse URI.
Les feuilles de styles importées et enveloppées dans une règle @media produiraient les mêmes effets, avec ce média, que les feuilles de style suivantes, néanmoins ces dernières peuvent épargner aux agents utilisateurs des téléchargements inutiles.
@import url("fineprint.css") print; @import url("bluish.css") projection, tv;
Si le type de média n'est pas précisé, l'import est inconditionnel. De même, si on spécifie le type de média 'all'.
6.4 La cascade
Les feuilles de style ont trois origines différentes : l'auteur, l'utilisateur et l'agent utilisateur.
- L'auteur : produit des feuilles de style pour un document source selon les conventions du langage de ce document. Par exemple en HTML, celles-ci peuvent être incorporées dans le document ou reliées à celui-ci.
- L'utilisateur : peut être capable d'indiquer une information de style pour un document particulier. Par exemple, celui-ci peut désigner une feuille de style contenue dans un fichier ou un agent utilisateur peut fournir l'interface pour produire une feuille de style personnelle (ou faire comme s'il l'avait fait).
- L'agent utilisateur: l'agent utilisateur conforme
doit appliquer sa feuille de style par défaut
(ou faire comme s'il l'avait fait) avant toutes les autres feuilles de style d'un document.
Cette feuille de style devrait présenter les éléments du langage du document
de façon à satisfaire au rendu généralement admis pour ceux-ci dans ce langage.
Par exemple, pour des navigateurs visuels, l'élément EM en HTML est rendu avec une police
en italique. Voir l'annexe A pour une feuille de style par défaut recommandée pour les documents HTML 4.0.
Noter que cette feuille de style par défaut peut varier si l'utilisateur change les réglages de son système (ex. les couleurs du système). Cependant, il peut être impossible de modifier les valeurs de celle-ci, en raison d'une implémentation réduite de l'agent utilisateur.
Les champs d'action de ces trois feuilles de style vont se recouper, leur interaction dépendant des règles de la cascade.
La cascade de CSS définit un ordre de priorité, ou poids, pour chaque règle de style. Quand plusieurs règles sont mises en œuvre, celle avec le plus grand poids a la préséance.
Les règles des feuilles de style de l'auteur ont, par défaut, plus de poids que celles de l'utilisateur. Au contraire, l'ordre de priorité est inversé pour les règles "!important". Les règles d'un auteur et d'un utilisateur sont prioritaires sur celles de la feuille de style par défaut de l'agent utilisateur.
Les feuilles de style importées suivent aussi la cascade, leur poids dépendant de leur ordre d'importation. Les règles définies dans une feuille de style donnée surclassent les règles de même poids importées d'autres feuilles de style. Les feuilles de style importées peuvent elles-même importer et remplacer d'autres feuilles de style, récursivement, et les mêmes règles de préséance leur sont appliquées.
6.4.1 L'ordre de cascade
Pour trouver la valeur d'une combinaison élément/propriété, les agents utilisateurs doivent suivre l'ordre de tri suivant :
- Trouver toutes les déclarations qui concernent l'élément et la propriété en question, pour le type de média visé. Celles-ci s'appliquent si le sélecteur correspond à cet élément ;
- Un tri primaire est effectué sur les déclarations selon leur poids et leur origine : pour une déclaration normale, les feuilles de style de l'auteur surclassent celles de l'utilisateur, ces dernières surclassant la feuille de style par défaut. Pour une déclaration avec "!important", celles-ci surclassent les déclarations normales. Une feuille de style importée est considérée comme ayant la même origine que celle qui l'a importée ;
- Un tri secondaire est effectué selon la spécificité des sélecteurs : les plus spécifiques surclasseront ceux plus généraux. Les pseudo-éléments et les pseudo-classes sont considérés respectivement comme des éléments et des classes normaux ;
- Un tri final selon l'ordre de spécification : si deux règles ont les mêmes poids, origines et spécificités, c'est la dernière survenue qui l'emporte. Les règles issues de feuilles de style importées sont considérées comme étant survenues avant chacune de celles de la feuille de style elle-même.
Mis à part le cas de la valeur "!important" attachée à certaines déclarations individuelles, cette stratégie donne la priorité aux feuilles de style de l'auteur sur celles de l'utilisateur. C'est pourquoi, il est important que l'agent utilisateur lui laisse la possibilité de neutraliser l'effet d'une feuille de style donnée (ex. au moyen d'un menu déroulant).
6.4.2 Les règles avec la valeur !important
CSS essaye de préserver un équilibre entre les prérogatives de l'auteur et celles de l'utilisateur. Par défaut, les règles d'une feuille de style de l'auteur surclassent celles de l'utilisateur (voir la règle de cascade numéro 3).
Par souci d'équilibre, les déclarations avec "!important" (les mots-clés "!" et "important" suivent la déclaration) établissent ainsi leur préséance sur les déclarations normales. Aussi bien les feuilles de style de l'auteur que celles de l'utilisateur peuvent contenir des déclarations avec "!important", celles de l'utilisateurs ayant priorité. Cette fonction de CSS améliore l'accessibilité des documents, offrant à ceux des utilisateurs qui ont des besoins particuliers (une grande taille de police, d'autres combinaisons de couleur, etc.), une certaine maîtrise de la présentation.
Remarque : Voici un changement sémantique par rapport à CSS1. Dans cette spécification-là, les règles avec "!important" d'un auteur avaient préséance sur celles de l'utilisateur.
Le fait de déclarer une propriété raccourcie (ex. 'background') avec la valeur "!important" confère ce poids à toutes ses sous-propriétés.
Dans l'exemple ci-dessous, la première règle de la feuille de style de l'utilisateur comporte une déclaration "!important", celle-ci surclasse la déclaration correspondante dans la feuille de l'auteur. La deuxième va également l'emporter, étant marquée "!important". Cependant, en l'absence de cette marque, la troisième de l'utilisateur ne sera pas retenue, au profit de la deuxième de l'auteur (par ailleurs, un style appliqué avec une propriété raccourcie). Autrement, sur la deuxième et la troisième règle de l'auteur, c'est la deuxième qui sera retenue, la troisième n'étant pas marquée "!important". Ceci montre que ce genre de déclaration a bien une fonction, même au sein des feuilles de style de l'auteur.
/* Extrait de la feuille de style de l'utilisateur */ P { text-indent: 1em ! important } P { font-style: italic ! important } P { font-size: 18pt } /* Extrait de la feuille de style de l'auteur */ P { text-indent: 1.5em !important } P { font: 12pt sans-serif !important } P { font-size: 24pt }
6.4.3 Le calcul de la spécificité d'un sélecteur
« errata : Voir la proposition pour le nouveau calcul de spécificité »
La spécificité d'un sélecteur se détermine de la manière suivante :
- compter le nombre d'attributs ID dans le sélecteur (= a) ;
- compter le nombre des autres attributs et pseudo-classes dans le sélecteur (= b) ;
- compter le nombre de noms d'élément dans le sélecteur (= c) ;
- ignorer les pseudo-éléments.
La concaténation des trois nombres a-b-c (dans un système de nombre avec une grande base) donne la spécificité.
* {} /* a=0 b=0 c=0 -> specificité = 0 */ LI {} /* a=0 b=0 c=1 -> specificité = 1 */ UL LI {} /* a=0 b=0 c=2 -> specificité = 2 */ UL OL+LI {} /* a=0 b=0 c=3 -> specificité = 3 */ H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificité = 11 */ UL OL LI.red {} /* a=0 b=1 c=3 -> specificité = 13 */ LI.red.level {} /* a=0 b=2 c=1 -> specificité = 21 */ #x34y {} /* a=1 b=0 c=0 -> specificité = 100 */
Pour HTML, les valeurs de l'attribut "style" sont des règles de feuille de style. Ces règles n'ont pas de sélecteur mais, dans l'optique du point 3 de l'algorithme de cascade, on considère qu'elles ont un sélecteur d'ID (spécificité : a=1, b=0, c=0). Et dans l'optique du point 4, on considère qu'elles adviennent après toutes les autres règles.
<HEAD> <STYLE type="text/css"> #x97z { color: blue } </STYLE> </HEAD> <BODY> <P ID=x97z style="color: red"> </BODY>
Dans cet exemple, la couleur de l'élément P serait rouge. Bien que la spécificité des deux déclarations soient la même, la déclaration dans l'attribut "style" surclassera celle dans l'élément STYLE à cause de la règle de cascade 4.
Remarque : La spécificité est seulement basée sur la forme du sélecteur. En effet, un sélecteur de la forme "[id=p33]" est compté comme un sélecteur d'attribut (a=0, b=1, c=0), même si l'attribut "id" est défini comme un "ID" dans la définition de type de document (DTD) du document source.
6.4.4 L'ordre de priorité des indications de présentation en dehors de CSS
L'agent utilisateur peut privilégier les indications de présentation provenant d'autres sources que les feuilles de style, par exemple l'élément FONT ou l'attribut "align" en HTML. Dans ce cas, ces indications doivent être traduites dans leurs règles équivalentes de CSS avec une spécificité égale à zéro. Ces règles sont censées se trouver au début de la feuille de style de l'auteur, permettant leur surclassement par les règles subséquentes de cette feuille de style.
Remarque : Durant une période de transition, cette manière de faire facilitera la coexistence des attributs stylistiques et des feuilles de style.
Remarque : Pour CSS1, ces indications de présentations en dehors de CSS avaient une spécificité égale à 1, et non à 0. Ce changement est du à l'introduction du sélecteur universel, qui a une spécificité de 0.
Document créé le 12/08/2006, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/css-rf-cascade.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.
Références
Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.