Certain d’entre vous ont peut être encore quelques soucis à comprendre les spécificités des css, spécialement avec les « pas si nouveaux » sélecteur CSS3.

illustration de specifishicity

Légende :

  • X-0-0 : représente les sélecteurs de type ID, illustrés par les requins.
  • 0-Y-0 : représente les sélecteurs de type class, attribut, pseudo-class , illustrés par les poissons
  • 0-0-Z : représente les sélecteurs de type balises, pseudo-élément, illustrés par Plankton.
  • * : le sélecteur universel n’a pas de valeur
  • +,>,~ : sont des combinateurs ils offrent plus de spécificités sur les sélecteurs, mais n’augmentent pas la valeurs.
  • :not(x) : le sélecteur négatif n’a lui non plus pas de poids.

Vous pouvez télécharger le pdf ici : PDF of fishy CSS specificity here

Ces spécificités déterminent quelle déclaration de propriété CSS est appliquée lorsque plusieurs règles s’appliquent à un même élément. Le sélecteur le plus spécifique est prioritaire. Si les spécifiées sont équivalentes, c’est la dernière règle qui est appliquée. En comprenant les spécificités, vous saisirez comment le navigateur prend en compte les règles CSS et comment sont appliquées ces dernières aux éléments html.

Prenons un exemple :

<p id="maDiv">You think water moves fast? You should see ice. It moves like it has a mind. Like it knows it killed the world once and got a taste for murder. After the avalanche, it took us a week to climb out.</p>

Si vous êtes familier des CSS, vous serez donc très familier avec les trois lignes suivantes :

#maDiv {color: red;} 1-0-0
.maClass {color: blue;} 0-1-0
p {color: yellow;} 0-0-1

Le bloc ci dessus contient trois règles qui ont un sélecteur qui pointe vers notre paragraphe. Si le système de cascade (CSS = cascading style sheets) ou l’ordre de placement du code etait le seul soucis, le contenu du paragraphe serait jaune. Mais, à différents sélecteurs, différents poids. Un ID prends le dessus sur une class qui prend le dessus sur une sélecteur de type balise. Donc notre paragraphe sera de couleur rouge.

Avec les sélecteurs CSS3, l’ordre est encore plus important pour comprendre les spécificités.
En remplaçant nos trois règles CSS par les suivantes, l’ordre du code devient prépondérant, puisque les class, sélecteurs d’attributs et pseudo-classes structurelles ont tous un poids équivalents.

p.maDiv {color: red} 0-1-1
p[id^='ma'] {color: blue} 0-1-1
p:nth-of-type(1n) {color: yellow} 0-1-1

Les spécificités du poids des sélecteurs

  1. !important : N’importe quelle déclaration avec le terme !important prend le dessus, même dans le cas d’utilisation de l’attribut style dans le code html. Si !important est déclaré plusieurs fois de manière concurrentielle, vous auteur du code CSS serez punis et toutes les précédentes règle sont actives. C’est comme si le poids des règles avec !important devenait : 1-X-A-B-C, pour cette propriété uniquement (là ou A, B, C sont les valeurs des parent du sélecteur). A cause de cet effet de bord !important ne devrait pas être utilisé, mais il reste bien utile pour des corrections de bug.
  2. style="" : Si l’auteur du code utilise des attributs style sur une balise html, le style déclaré dans l »attribut prendra le dessus sur toutes les déclarations faites dans une feuille de style externe ou dans l’entête du document html, à l’exception des déclarations contenant !important. Tous ceux qui mettent des style dans les balises doivent être punis. Pour information, le code javascript modifiant le style des ablises ajoute des attribut style à la balise concernée (… id="monID" style="color: purple" …). Le poids du code CSS dans les attributs style est : 1-0-0-0.
  3. ID : Parmi les sélecteur que vous inclurez dans feuille de style extern ou dans l’entête du document, Les ID sont ceux qui ont le plus de poids le poids d’un ID est : 1-0-0 par ID.
  4. class/pseudo-class/attributes: Comme montré dans le second exemple de code CSS ci-dessus, les sélecteurs de type class, les sélecteurs d’attribut et les pseudo-classes ont tous le même poids soit 0-1-0.
  5. type: les sélecteurs de type balise et les pseudo-élements, :first-letter ou :after ont la valeur la plus basse 0-0-1 par élément.

Si plus d’un sélécteur a la même spécificité, alors interviens la règle des cascade, la dernière règle déclarée prends la main.

Calcul des spécificités

Pour calculer les spécificités d’un déclaration, il suffit de compter les éléments type, class/pseudo-classe/attributs et ID dans vos déclarations, puis ensuite les additionné séparemment par groupe en utilisant l’expression X-Y-Z.

  • Pour calculer X, compter le nombre d’ID dans vos déclarations
  • Pour calculer Y, comptez le nombre de class, pseudo-class, et sélécteurs d’attributs, attention il ne faut prendre en compte :not, mais ses arguments, par ex : :not(.loud), il faut compter le .loud.
  • Pour calculer Z, comptez le nombre de sélecteur balise et les pseudo-éléments.

Par exemple, si vous avez :

  • 1 ID
  • 12 class/pseudo-class/attributs
  • 5 type

Vous sur-déclarez vos règles mais la valeur serait : 1-12-5, noté que la valuer final n’est pas un nombre mais plutot une matrice. Peu importe combien de class, attribute, pseudo-class vous avez, un seul et unique ID chamboulera tout votre code. Si vous utilisez l’exemple de speciFISHity, aucune quantité de plankton (éléments) ne pourra supplanter un poisson (class). Aucun poisson ne pourra battre un requin (ID). Le match est perdu d’avance pour le requin face au tanker (style inline) et même ce dernier succombera à une explosion atomique (!important).

Les trucs un peu moins évidents :

  • Le sélecteur *, ou global, n’a pas de valeur. *.maClass sera supplanté par p.maClass, même si il est sur la dernière ligne de la dernière feuille de style.
  •  Les combinateurs, comme ~, > et +n’ont pas de valeurs non plus, ils vous aident à être plus spécifique et peuvent être supplanté par le même par un sélecteur de même poids.
     ul > li {color: blue;} 0-0-2
     ul li {color: red;} 0-0-2
    

    Dans l’exemple ci-dessus le contenu de la balise li sera rouge puisque les deux déclarations ont un même poids, c’est la cascade qui prend la main.

  • Les spécificités ne sont pas hérités. Si vous déclarez 27 valeurs pour un élément parent, d’un paragraphe et rajouter même !important, mais que vous déclarez des règles pour le paragraphe séparément, les propriétés déclarées pour l’élément s’appliquerons. L’héritage ne battra pas ces déclarations.
    <div id="x" class="y"><p>Hi</p></div>

    div#x.y {color:red;} 1-1-0
    p {color: blue;} 0-0-1
    

    Le paragraphe sera bleue et non rouge, même si la première déclaration est plus spécifique et que les couleurs sont héritées, la seconde déclaration s’appliquera à l’élément alors que la première est appliquée au parent. La couleur n’est héritée que si elle n’est pas spécifiée dans les descendants. Et dans ce cas elle est declarée.

Traduit de : http://www.standardista.com/css3/css-specificity/