web-dev-qa-db-fra.com

Points de spécificité CSS

En recherchant la spécificité, je suis tombé sur ce blog - http://www.htmldog.com/guides/cssadvanced/specificity/

Il indique que la spécificité est un système de pointage pour CSS. Il nous dit que les éléments valent 1 point, les classes valent 10 points et les identifiants valent 100 points. Il indique également que ces points sont totalisés et que le montant global correspond à la spécificité de ce sélecteur.

Par exemple:

corps = 1 point
body .wrapper = 11 points
body .wrapper #container = 111 points

Donc, en utilisant ces points, les CSS et HTML suivants entraîneront sûrement le texte en bleu:

CSS:

#a {
    color: red;
}

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o {
  color: blue;
}

HTML:

<div class="a">
  <div class="b">
    <div class="c">
      <div class="d">
        <div class="e">
          <div class="f">
            <div class="g">
              <div class="h">
                <div class="i">
                  <div class="j">
                    <div class="k">
                      <div class="l">
                        <div class="m">
                          <div class="n">
                            <div class="o" id="a">
                              This should be blue.
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

RÉSULTAT:

http://jsfiddle.net/hkqCF/

Pourquoi le texte est-il rouge lorsque 15 classes équivaudraient à 150 points par rapport à 1 ID qui équivaut à 100 points?

MODIFIER:

Donc, apparemment, les points ne sont pas simplement totalisés, ils sont concaténés. En savoir plus à ce sujet ici - http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html MAIS, cela signifie-t-il que les classes de notre sélecteur = 0,0,15,0 OU0,1,5,0?

Mon instinct me dit que c'est le premier, car nous SAVONS que la spécificité du sélecteur ID ressemble à ceci: 0,1,0,0

121
Sam

la réponse de Pekka est pratiquement correct, et probablement la meilleure façon de penser au problème.

Cependant, comme beaucoup l'ont déjà souligné, la recommandation CSS du W3C stipule que "la concaténation des trois nombres a-b-c (dans un système numérique avec une grande base) donne la spécificité." Donc, le geek en moi devait juste comprendre à quel point cette base est grande.

Il s'avère que la "très grande base" employée (au moins par les 4 navigateurs les plus utilisés)*) pour implémenter cet algorithme standard est 256 ou 28.

Cela signifie qu'un style spécifié avec 0 id et 256 noms de classe sera surpassera un style spécifié avec seulement 1 id. J'ai testé cela avec quelques violons:

Il y a donc effectivement un "système de points", mais ce n'est pas la base 10. C'est la base 256. Voici comment cela fonctionne:

(28)2 ou 65536, multiplié par le nombre d'identifiants dans le sélecteur
+ (28)1 ou 256, fois le nombre de noms de classe dans le sélecteur
+ (28) ou 1, fois le nombre de noms de balises dans le sélecteur

Ce n'est pas très pratique pour les exercices au dos de l'enveloppe pour communiquer le concept.
C'est probablement pourquoi les articles sur le sujet utilisent la base 10.

***** [Opera utilise 216 (voir le commentaire de karlcow). Certains autres moteurs de sélection utilisent infini - en fait aucun système de points (voir le commentaire de Simon Sapin).]

Mise à jour, juillet 2014:
Comme Blazemonger l'a souligné plus tôt dans l'année, les navigateurs webkit (chrome, safari) semblent désormais utiliser une base plus élevée que 256. Peut-être 216, comme Opera? IE et Firefox utilisent toujours 256.

135
Faust

Bonne question.

Je ne peux pas le dire avec certitude - tous les articles que je parviens à trouver évitent l'exemple de plusieurs classes, par exemple ici - mais je suppose que quand il s'agit de comparer la spécification entre un sélecteur de classe et un ID, la classe est calculée avec une valeur de 15 uniquement, quelle que soit sa précision.

Cela correspond à mon expérience du comportement de la spécificité.

Cependant, il y a doit un certain empilement de classes car

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o

est plus spécifique que

.o

la seule explication que j'ai est que la spécificité des classes empilées est calculée uniquement les unes par rapport aux autres mais pas par rapport aux ID.

Mise à jour : je l'ai à mi-chemin maintenant. Ce n'est pas un système de points et les informations sur les classes de 15 points sont incorrectes. C'est un système de numérotation en 4 parties très bien expliqué ici .

Le point de départ est de 4 chiffres:

style  id   class element
0,     0,   0,    0

Selon explication du W3C sur la spécificité , les valeurs spécifiques pour les règles susmentionnées sont:

#a            0,1,0,0    = 100
classes       0,0,15,0   = ... see the comments

il s'agit d'un système de numérotation avec une très grande base (non définie?).

Ma compréhension est que, parce que la base est très grande, aucun nombre dans la colonne 4 ne peut battre un nombre> 0 dans la colonne 3, de même pour la colonne 2, la colonne 1 .... Est-ce correct?

Je serais intéressé si quelqu'un avec une meilleure compréhension des mathématiques que moi pourrait expliquer le système de numérotation et comment le convertir en décimal lorsque les éléments individuels sont plus grands que 9.

28
Pekka 웃

L'actuel Projet de travail de sélection de niveau 4 fait un bon travail de description de la spécificité en CSS:

Les spécificités sont comparées en comparant les trois composants dans l'ordre: la spécificité avec une valeur plus grande [~ # ~] une [~ # ~] est plus spécifique; si les deux [~ # ~] a [~ # ~] valeurs sont liées, alors la spécificité avec une plus grande [~ # ~] b [~ # ~] la valeur est plus spécifique; si les deux [~ # ~] b [~ # ~] valeurs sont également liées, alors la spécificité avec un plus grand la valeur c est plus spécifique; si toutes les valeurs sont liées, les deux spécificités sont égales.

Cela signifie que les valeurs A, B et C sont complètement indépendantes les unes des autres.

15 classes ne donnent pas à votre sélecteur un score de spécificité de 150, il lui donne une valeur [~ # ~] b [~ # ~] de 15 Une seule valeur [~ # ~], une valeur [~ # ~] suffit pour vaincre cela.

Comme métaphore, imaginez une famille de 1 grand-parent, 1 parent et 1 enfant. Cela pourrait être représenté par 1,1,1 . Si le parent a 15 enfants, cela ne fait pas soudainement d'eux un autre parent ( 1,2,0 ). Cela signifie que le parent a beaucoup plus de responsabilités qu'il n'en avait avec un seul enfant ( 1,1,15 ). ;)

La même documentation poursuit en disant:

En raison des limitations de stockage, les implémentations peuvent avoir des limites sur la taille de [~ # ~] a [~ # ~] , [~ # ~] b [~ # ~] , ou c . Si tel est le cas, les valeurs supérieures à la limite doivent être fixées à cette limite et non déborder.

Cela a été ajouté pour résoudre le problème présenté dans réponse de Faust , où les implémentations CSS en 2012 ont permis aux valeurs de spécificité de déborder les unes dans les autres.

En 2012, la plupart des navigateurs ont implémenté une limitation de 255, mais cette limitation a pu déborder. 255 classes avaient un A, B, c score de spécificité de 0,255,0 , mais 256 classes ont débordé et ont eu un A, B, c score de 1,0,0 . Soudain, notre valeur [~ # ~] b [~ # ~] est devenue notre [~ # ~] a [ ~ # ~] valeur. La documentation des sélecteurs de niveau 4 irradie complètement ce problème en indiquant que la limite ne peut jamais être autorisée à déborder. Avec cette implémentation, les classes 255 et 256 auraient les mêmes A, B, c score de 0,255,0 .

Le problème donné dans la réponse de Faust a depuis été corrigé dans la plupart des navigateurs modernes.

9
James Donnelly

J'utilise actuellement le livre CSS Mastery: Advanced Web Standards Solutions .

Le chapitre 1, page 16 dit:

Pour calculer la spécificité d'une règle, chaque type de sélecteur se voit attribuer une valeur numérique. La spécificité d'une règle est ensuite calculée en additionnant la valeur de chacun de ses sélecteurs. Malheureusement, la spécificité n'est pas calculée en base 10 mais un nombre de base élevé et non spécifié. Cela permet de garantir qu'un sélecteur très spécifique, tel qu'un sélecteur d'ID, n'est jamais remplacé par de nombreux sélecteurs moins spécifiques, tels que des sélecteurs de type.

(c'est moi qui souligne) et

La spécificité d'un sélecteur se décompose en quatre niveaux constitutifs: a, b, c et d.

  • si le style est un style en ligne, alors a = 1
  • b = le nombre total de sélecteurs d'id
  • c = le nombre de sélecteurs de classe, pseudo-classe et attribut
  • d = le nombre de sélecteurs de type et de sélecteurs de pseudo-éléments

Il ajoute que vous pouvez souvent faire le calcul en base 10, mais uniquement si toutes les colonnes ont des valeurs inférieures à 10.


Dans vos exemples, les identifiants ne valent pas 100 points; chacun vaut [0, 1, 0, 0] points. Par conséquent, un id bat 15 classes car [0, 1, 0, 0] est supérieur à [0, 0, 15, 0] dans un système de nombres à base élevée.

8
Matt Fenwick

J'aime comparer le classement de la spécificité au tableau des médailles des Jeux Olympiques (méthode de la première médaille d'or - basée d'abord sur le nombre de médailles d'or, puis d'argent puis de bronze).

Cela fonctionne également avec votre question (grand nombre de sélecteurs dans un groupe de spécificité). La spécificité a considéré chaque groupe séparément. Dans le monde réel, j'ai très rarement vu des cas avec plus d'une douzaine de sélecteurs).

Il existe également un assez bon calculateur de spécificité ici . Vous pouvez y mettre votre exemple (#a et .a .b .c .d .e .f .g .h .i .j .k .l .m .n .o) et voir les résultats.

Exemple de tableau des médailles des Jeux Olympiques de Rio 2016 ressemble à enter image description here

4
rkarczmarczyk

Je ne pense pas que l'explication du blog soit correcte. La spécification est ici:

http://www.w3.org/TR/CSS2/cascade.html#specificity

Les "points" d'un sélecteur de classe ne peuvent pas s'additionner pour être plus importants qu'un sélecteur "id". Ça ne marche pas comme ça.

3
Matthew Wilson

Je dirais que:

Element < Class < ID

Je pense qu'ils ne se cumulent en fonction de ce que vous obtenez que s'il est multiple de la même chose. Ainsi, une classe remplacera toujours l'élément et l'ID toujours au-dessus de la classe, mais s'il s'agit de celui des 4 éléments où 3 est bleu et 1 rouge, il sera bleu.

Par exemple:

.a .b .c .d .e .f .g .h .i .j .k .l
{
color: red;
}

 .m .n .o
{
color blue;
}

Devrait devenir rouge.

Voir Exemple http://jsfiddle.net/RWFWq/

"si les 5e disent rouge et 3 disent bien bleu, je vais devenir rouge"

1
Sphvn