Contenu
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").
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é) :
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.
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.
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.
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 12pt mais, par exemple, d'une police de 11pt, la valeur réelle de la propriété 'font-size' de ces éléments pourrait être '11pt'.
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.
[Errata: 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; }
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'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'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'.
Les feuilles de style ont trois origines différentes : l'auteur, l'utilisateur et l'agent utilisateur.
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. Des règles étant spécifiées dans une feuille de style donnée, celles-ci remplacent les règles de même poids importées d'une autre feuille de style. Les feuilles de style importées peuvent elles-même importer et remplacer d'autres feuilles de style, récursivement, les mêmes règles de préséance leur étant appliquées.
Pour trouver la valeur d'une combinaison élément/propriété, les agents utilisateurs doivent suivre l'ordre de tri suivant :
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).
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 }
La spécificité d'un sélecteur est déterminée comme suit :
La spécificité est obtenue en assemblant les quatre nombres a-b-c-d (dans un système de nombres avec une base étendue).
Quelques exemples de plus en plus spécifiques :
* {} /* a=0 b=0 c=0 d=0 -> spécificité = 0, 0, 0, 0 */ LI {} /* a=0 b=0 c=0 d=1 -> spécificité = 0, 0, 0, 1 */ UL LI {} /* a=0 b=0 c=0 d=2 -> spécificité = 0, 0, 0, 2 */ UL OL+LI {} /* a=0 b=0 c=0 d=3 -> spécificité = 0, 0, 0, 3 */ H1 + *[REL=up]{} /* a=0 b=0 c=1 d=1 -> spécificité = 0, 0, 1, 1 */ UL OL LI.red {} /* a=0 b=0 c=1 d=3 -> spécificité = 0, 0, 1, 3 */ LI.red.level {} /* a=0 b=0 c=2 d=1 -> spécificité = 0, 0, 2, 1 */ #x34y {} /* a=0 b=1 c=0 d=0 -> spécificité = 0, 1, 0, 0 */ style=" " /* a=1 b=0 c=0 d=0 -> spécificité = 1, 0, 0, 0 */
Pour HTML, les valeurs de l'attribut "style" sont des règles de feuille de style. Ces règles n'ont pas de sélecteurs, 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 surviennent après toutes les autres règles.
<HEAD> <TITLE>Exemple de spécificité</TITLE> <STYLE type="text/css"> p#x97z { color: red } </STYLE> </HEAD> <BODY> <P ID=x97z style="color: green"> </BODY>
Dans l'exemple ci-dessus, la couleur de l'élément P serait verte. La déclaration dans l'attribut 'style' va surclasser celle dans l'élément STYLE du fait de la règle de cascade 3, puisqu'elle a une plus grande spécificité.
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 le DTD du document source.
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 O. Ce changement est du à l'introduction du sélecteur universel, qui a une spécificité de 0.