Gardez à l'esprit que lorsqu'un navigateur fait correspondre des sélecteurs, il dispose d'un élément (celui pour lequel il essaie de déterminer le style) et de toutes vos règles et de leurs sélecteurs, et il doit trouver quelles règles correspondent à l'élément. C'est différent de la méthode habituelle de jQuery, par exemple, où vous n'avez qu'un seul sélecteur et vous devez trouver tous les éléments qui correspondent à ce sélecteur.
Si vous n'aviez qu'un seul sélecteur et qu'un seul élément à comparer à ce sélecteur, la comparaison de gauche à droite serait plus logique dans certains cas. Mais c'est décidément no la situation du navigateur. Le navigateur essaie d'afficher Gmail ou autre et a l'une des caractéristiques suivantes <span>
qu'il essaie de styliser et les plus de 10 000 règles que Gmail met dans sa feuille de style (je n'invente pas ce chiffre).
En particulier, dans la situation où le navigateur regarde la plupart des sélecteurs qu'il considère Ne le fais pas. correspondent à l'élément en question. Le problème consiste donc à décider qu'un sélecteur ne correspond pas le plus rapidement possible ; si cela nécessite un peu de travail supplémentaire dans les cas qui correspondent, vous gagnez quand même grâce à tout le travail que vous économisez dans les cas qui ne correspondent pas.
Si vous commencez par faire correspondre la partie la plus à droite du sélecteur avec votre élément, il y a de fortes chances qu'il ne corresponde pas et que vous ayez terminé. S'il y a correspondance, vous devez faire plus de travail, mais seulement proportionnellement à la profondeur de votre arbre, qui n'est pas si grande dans la plupart des cas.
D'un autre côté, si vous commencez par faire correspondre la partie la plus à gauche du sélecteur... avec quoi allez-vous la faire correspondre ? Vous devez commencer à parcourir le DOM, à la recherche de noeuds qui pourraient correspondre. Découvrir qu'il n'y a rien qui correspond à la partie la plus à gauche peut prendre un certain temps.
Les navigateurs correspondent donc à partir de la droite ; cela donne un point de départ évident et vous permet de vous débarrasser très rapidement de la plupart des sélecteurs candidats. Vous pouvez voir quelques données à http://groups.google.com/group/mozilla.dev.tech.layout/browse_thread/thread/b185e455a0b3562a/7db34de545c17665 (bien que la notation soit confuse), mais le résultat est que pour Gmail en particulier, il y a deux ans, pour 70 % des paires (règle, élément), vous pouviez décider que la règle ne correspondait pas après avoir simplement examiné les parties tag/class/id du sélecteur le plus à droite pour la règle. Le chiffre correspondant pour la suite de tests de performance pageload de Mozilla était de 72 %. Il vaut donc la peine d'essayer de se débarrasser de ces 2/3 de toutes les règles aussi vite que possible et de ne se préoccuper ensuite que de la correspondance du 1/3 restant.
Notez également que d'autres optimisations sont déjà effectuées par les navigateurs pour éviter d'essayer de faire correspondre des règles qui ne le seront certainement pas. Par exemple, si le sélecteur le plus à droite a un identifiant et que cet identifiant ne correspond pas à l'identifiant de l'élément, Gecko ne tentera pas du tout de faire correspondre ce sélecteur à cet élément : l'ensemble des "sélecteurs avec identifiants" qui sont tentés provient d'une table de hachage sur l'identifiant de l'élément. Voici donc 70% des règles qui ont de bonnes chances de correspondre à cet élément. toujours ne correspondent pas après avoir considéré uniquement la balise/classe/id du sélecteur le plus à droite.
5 votes
3. Non - quelle que soit la façon dont vous le lisez, le sélecteur correspond toujours au même ensemble d'éléments.
1 votes
La méthode d'analyse que vous suggérez n'aurait pas vraiment d'effet puisqu'elle nécessite un accès fréquent au DOM. Je l'analyserais de gauche à droite, et vraisemblablement, les sélecteurs tels que celui de jQuery l'analysent également de gauche à droite.
0 votes
@Sime Vidas - Alors pourquoi le faire de droite à gauche ?
0 votes
@JCOC611 - Mais pourquoi les moteurs de navigation ne le font-ils pas ?
0 votes
@JCOC611 Je pensais que le moteur de grésillement de jQuery traversait droite->gauche et utilisait des optimisations intégrées (comme lorsque le sélecteur commence par un ID).
44 votes
Pour ce que ça vaut, un navigateur ne peut pas supposer que vos identifiants sont uniques. Vous pourriez coller le même id="foo" partout dans votre DOM, et un
#foo
Le sélecteur devrait correspondre à tous ces nœuds. jQuery a la possibilité de dire que $("#foo") ne retournera toujours qu'un seul élément, car il définit sa propre API avec ses propres règles. Mais les navigateurs doivent implémenter CSS, et CSS dit de faire correspondre tous les éléments du document avec l'ID donné.2 votes
La question semble porter sur le sélecteur correspondant à et non sur le sélecteur analyse syntaxique de .
2 votes
@Boris Zbarsky - Les spécifications HTML et CSS stipulent que les ID doivent être uniques. Tout faire correspondre est une décision prise pour que la récupération d'erreur puisse être effectuée sur les mauvais documents, pas parce que la spécification le dit.
2 votes
@Quentin : La spécification CSS3 sur Sélecteurs d'identité un sélecteur d'ID correspond à "tout élément" ayant cet ID plutôt qu'à "l'élément" ayant cet ID.
2 votes
@BoltClock - il est également dit "Ce qui rend les attributs de type ID spéciaux est que deux de ces attributs ne peuvent avoir la même valeur dans un document conforme".
4 votes
Quentin Dans un document "non conforme" (à HTML), les ID peuvent être non uniques, et dans ces documents, CSS exige que tous les éléments correspondent à cet ID. Le CSS lui-même n'impose aucune exigence normative sur l'unicité des ID ; le texte que vous citez est informatif.
5 votes
@Boris Zbarsky Ce que fait jQuery dépend du chemin de code dans jQuery. Dans certains cas, jQuery utilise l'API NodeSelector (native
querySelectorAll
). Dans les autres cas, on utilise Sizzle. Sizzle ne fait pas correspondre plusieurs ID, mais QSA le fait (AYK). Le chemin emprunté dépend du sélecteur, du contexte, du navigateur et de sa version. L'API de requête de jQuery utilise ce que j'ai appelé "Native First, Dual Approach". J'ai écrit un article à ce sujet, mais il n'est plus disponible. Mais vous pouvez le trouver ici : fortybelow.ca/housted/dhtmlkitchen/JavaScript-Query-Engines.html1 votes
@BorisZbarsky : A aucun moment dans toute la spécification -- dans toute version de la spécification - ne mentionne pas le résultat d'une tentative d'application de CSS à un document non valide. (En fait, l'un des errata est une note adressée à fixer un HTML mal formé, plutôt que de profiter de cette occasion pour ajouter une note indiquant que les styles doivent quand même être appliqués). Quant à la partie concernant l'unicité des ID ? C'est est normative, comme tous les autres textes de la spécification, sauf indication contraire.
2 votes
@cHao Il n'existe pas de "document invalide" en ce qui concerne les CSS. CSS fonctionne simplement sur un arbre d'éléments abstraits. Le HTML définit la manière dont cet arbre est construit, et il définit comment le faire même pour les documents qui ne répondent pas aux critères de conformité de la rédaction. Ainsi, le résultat de l'application de CSS à un document avec des ID dupliqués est en fait complètement défini par la combinaison des deux spécifications. Quant à son caractère normatif, il est certain qu'il l'est : en tant que norme de l auteur exigence. Les identifiants dupliqués ne seront pas validés, mais cela n'affecte pas la manière dont les UA sont censés les traiter.
2 votes
@cHao Voici un exemple utilisant le DOM (qui fonctionne également sur un arbre d'éléments) au lieu de CSS. Jetez un coup d'œil à dom.spec.whatwg.org/#dom-document-getelementbyid et notez l'utilisation de "le premier élément, dans l'ordre de l'arbre". Pourquoi pensez-vous que cela dit cela, exactement ? Parce que les identifiants peuvent en fait être dupliqués si l'auteur n'a pas rédigé un document validant, et le DOM doit gérer cela.
2 votes
Le DOM le fait. Les CSS ne le font pas. Il serait tout aussi correct d'appliquer
#whatever
à exactement l'élément retourné pardocument.getElementById('whatever')
. Il est explicitement indiqué dans les CSS que les ID sont uniques. Si vous enfreignez cette règle, il n'y a aucune règle sur la façon dont l'implémentation doit se comporter.0 votes
@BorisZbarsky Parce que le DOM doit être capable de gérer les documents invalides, et qu'il spécifie comment gérer une situation qui ne devrait pas exister sans exploser ?
0 votes
@RobertMcKee Bien sûr, mais les mêmes considérations s'appliquent aux CSS.
3 votes
@cHao Le fait est que les membres du groupe de travail CSS ne sont pas d'accord avec vous, les implémentations des navigateurs ne sont pas d'accord avec vous, et les sites web dépendent du comportement des implémentations des navigateurs : il est en fait courant pour les sites d'avoir des ID répétés et de dépendre du style de l'ID pour le style de tous les éléments. Donc, à part la pureté théorique, quel est l'avantage de votre argument, si je peux me permettre de demander ?
1 votes
@BorisZbarsky Vous avez soulevé quelques points intéressants, cependant, je ne vois pas comment vous pensez que les membres du groupe de travail CSS voient les choses de votre façon alors que les seules choses que j'ai vues dans la spécification disent le contraire. Certaines implémentations de navigateurs peuvent ou veulent donner le même style à plusieurs éléments ayant la même valeur d'ID (pas tous, mais au moins les 4 premiers), et il n'est vraiment pas courant que des sites aient des ID répétés et en dépendent. Il est en fait assez rare d'en voir un, et je ne pense pas en avoir jamais vu un en dépendre. Pouvez-vous en citer 3 ? Je peux vous dire que la bibliothèque javascript la plus couramment utilisée n'est PAS d'accord avec vous.
0 votes
Désolé, je devrais dire que deux des bibliothèques javascript les plus utilisées (jQuery et prototype.js) ne renvoient qu'un seul élément lorsqu'on leur demande de sélectionner par id. Prototype : jsfiddle.net/CTZT6 jQuery : jsfiddle.net/CTZT6/1
0 votes
MooTools renvoie également un seul élément lorsqu'on lui donne un sélecteur d'id : jsfiddle.net/CTZT6/2
2 votes
@BorisZbarsky : L'avantage est de ne pas avoir à se soucier d'un comportement qui n'a été spécifié nulle part. Le groupe de travail CSS ne semble pas être d'accord avec l'idée d'un comportement qui n'est pas spécifié nulle part. soit de nous, étant donné qu'ils n'ont fait aucune déclaration officielle dans un sens ou dans l'autre - à l'exception de la déclaration officielle dans les spécifications selon laquelle les ID sont uniques, bien sûr, ce qui donne plus de poids à mon argument qu'au vôtre. requerido pour agir comme il le fait, dans la mesure où CSS est concerné, et s'appuyer sur un comportement non spécifié est tout simplement un mauvais codage.
0 votes
@BorisZbarsky : L'avantage est que également en promouvant un comportement cohérent garanti entre CSS et JS. Si vos identifiants ne sont pas uniques, vous n'avez absolument aucune garantie sur ce qui va se passer, à moins que vous ne vouliez apposer sur votre page un avertissement du type "ce site fonctionne en...".
1 votes
@RobertMcKee Je pense qu'ils voient les choses à ma façon parce que je leur ai parlé. Ce que vous pouvez faire aussi : il suffit d'envoyer un courrier à www-style@w3.org. Et en ce qui concerne les sites, il y a beaucoup de choses qui utilisent des ids pour le style alors qu'ils devraient utiliser des classes.... et non, jQuery ne fait pas ça quand vous utilisez ses trucs de sélection, mais ça ne veut pas dire que les sites ne dépendent pas de la technologie CSS moteur qui le fait.
3 votes
@cHao Ne pas s'inquiéter d'un comportement qui "n'est spécifié nulle part" est inutile s'il s'agit d'une norme de facto. Bien sûr, ce comportement est spécifié : CSS dit de faire correspondre les choses qui ont un ID donné et que le langage du document définit ce que signifie avoir un ID. Le langage HTML définit quels éléments ont quels ID. Le résultat est que plusieurs éléments peuvent avoir le même ID. Il faut vraiment essayer de déformer les spécifications et de s'appuyer sur les parties non normatives pour arriver à une autre conclusion.
1 votes
@BorisZbarsky : Il ne faut rien de plus qu'une lecture littérale de tous les documents existants. normatif documentation. Aucune torsion n'est nécessaire. Il faut en fait plus, comme une dépendance à un comportement qui n'est documenté nulle part, pour arriver à la conclusion qu'un comportement non défini est en quelque sorte défini.
0 votes
@cHao Oh, je vois le problème de fond. Il n'existe pas de "comportement indéfini" dans les spécifications Web (pas les bonnes, du moins). Nous avons essayé ; ce fut un échec cuisant. Les spécifications définissent maintenant le comportement dans toutes les situations. Si vous constatez un comportement indéfini, soit il s'agit d'un bug de la spécification, soit il vous manque quelque chose.
0 votes
@BorisZbarsky : Montrez-moi la spécification qui définit comment CSS doit se comporter lorsque l'UA est présenté avec un document invalide. La spécification CSS ne le fait certainement pas, et en fait elle sort de son chemin no à.
0 votes
@BorisZbarsky : En fait, je me contenterai même de normes de facto dans ce cas. Montrez-moi où les fabricants de navigateurs ont documenté le comportement de leurs UAs respectifs dans un tel cas.
2 votes
@cHao où la spécification CSS dit-elle quelque chose de ce genre ? Elle n'a même pas le concept de "document invalide" dans le texte normatif. En outre, notez que dev.w3.org/csswg/selectors4/#id-selectors dit explicitement "Il est possible dans les documents non conformes que plusieurs éléments correspondent à un seul sélecteur d'identification."
1 votes
@BorisZbarsky : Voir, maintenant, le texte quelque peu Ce qui ressemble à cela est essentiellement ce qui doit être dans une spécification finie avant que vous puissiez dire "CSS exige" quelque chose. Il faut cependant que ce soit formulé de manière plus explicite avant que cela ne compte comme une exigence, quelque chose comme "Dans un document non conforme, un sélecteur d'ID doit correspondre à tous les éléments dont l'attribut ID est le même que l'identifiant dans le sélecteur". "Possible" est plus un "peut" qu'un "doit", et il est assez facile d'imaginer qu'une UA supprime les attributs d'identification illégaux du document, à moins qu'il ne soit explicitement demandé de les conserver pour une raison quelconque.
1 votes
@cHao Le texte que je cite est informatif, tout comme le reste de ce texte. Il n'y a aucun changement dans ce que la spécification exige, juste une explication plus claire pour les personnes qui semblaient être confuses sur ce qu'elle exige. C'est pourquoi il ne dit pas "doit" : c'est un non-sens pour un texte informatif.
1 votes
@BorisZbarsky : Ainsi donc, il n'y a toujours pas de texte normatif décrivant une exigence pour un comportement particulier dans ce cas.
4 votes
@cHao Bien sûr qu'il y en a un. Vous l'ignorez juste volontairement.
0 votes
@BorisZbarsky : Alors montrez-moi . Rendez-le suffisamment évident pour que même moi je ne puisse pas le réfuter. Il suffirait d'un lien vers un texte normatif énonçant clairement cette exigence. J'ai demandé une demi-douzaine de fois de voir un tel texte, et vous n'avez toujours pas produit de lien. J'ai moi-même examiné les spécifications un certain nombre de fois, et je n'ai pas pu trouver de mots énonçant une telle exigence - et le seul texte que j'ai vu jusqu'à présent, soit de manière ostensible, soit de manière indirecte. évite en indiquant un, ou en déclarant explicitement que les identifiants doivent être uniques. Généralement les deux.
1 votes
Il n'y a pas de texte normatif qui le dise explicitement, tout comme il n'y a pas de texte normatif qui dise explicitement que deux éléments avec la même classe sont mis en correspondance par un sélecteur de classe et aucun texte normatif qui dise que le navigateur ne doit pas planter lors de l'analyse des CSS. Les éléments normatifs pertinents sont les suivants w3.org/TR/css3-selectors/#id-selectors qui dit : "Un sélecteur d'identification représente une instance d'élément dont l'identifiant correspond à l'identifiant du sélecteur d'identification." Il ne définit pas comment dire quel est l'identifiant de l'élément ; cela dépend du langage du document, donc du HTML.
1 votes
@cHao Et la spécification du langage de document a "L'attribut id spécifie l'identifiant unique (ID) de son élément. [DOM]" C'est tout. C'est toute l'étendue du texte normatif sur le sujet pour les implémenteurs de l'UA. Si vous l'implémentez simplement sans essayer de lire entre les lignes, vous obtenez le comportement que tous les navigateurs ont.
0 votes
@BorisZbarsky : Et si vous faire "lire entre les lignes", il est tout à fait possible d'écrire une UA qui suit la spécification à la lettre et qui ne fait toujours pas ce que vous prétendez (sans preuve) que la spécification "exige". Puisque par définition, une identifiant unique dupliqué ne peuvent pas exister, il n'y a aucun texte disant ce que le navigateur doit faire avec les documents qui les possèdent. Il pourrait laisser tomber tous les doublons sauf le premier, par exemple, et être 100% compatible avec HTML5 et CSS3. Il pourrait garder le premier, le dernier ou un des doublons au hasard et être compatible avec HTML4 -- et, encore une fois, avec CSS3.
0 votes
@BorisZbarsky : Un navigateur qui ferait l'une ou l'autre de ces choses ne serait même pas capable d'en styliser plusieurs.
#whatever
parce qu'il n'y aura jamais être plus d'un#whatever
. Et d'après toutes les spécifications que j'ai pu voir, ce navigateur est toujours 100% conforme à toutes ces spécifications.0 votes
@cHao Lire entre les lignes avec les spécifications vous causera des problèmes. En particulier, vous ne serez pas conforme à la spécification dans ce cas, car les auteurs de la spécification supposent que vous ne lisez PAS entre les lignes. S'ils devaient supposer que vous le faites et couvrir toutes les possibilités de lecture entre les lignes dans la spécification, les spécifications deviendraient ridiculement lourdes.
0 votes
@cHao Dans tous les cas, si vous pensez que les spécifications doivent être améliorées, n'hésitez pas à soumettre vos commentaires. www-style@w3.org pour CSS, public-html@w3.org pour HTML.
1 votes
@BorisZbarsky : Je considère que cela fait partie de mon travail de lire entre les lignes -- de vérifier mes hypothèses et de faire la différence entre ce qui est réellement requerido et ce qui est simplement le mécanisme le plus couramment mis en œuvre aujourd'hui. Oui, spécifier complètement le comportement d'erreur mène à un trou de lapin très profond, et aller jusqu'au bout rend la spécification difficile à manier... mais tout comportement non spécifié est, par définition, une erreur de comportement. un spécifié, et est donc ouvert à l'interprétation. IMO HTML5 n'aurait jamais dû descendre dans le trou en premier lieu, précisément pour cette raison. (Enfin, ça et le fait qu'aller jusqu'au bout rendrait le HTML valide non pertinent).
2 votes
@cHao Votre idée de la façon dont les spécifications web fonctionnent n'est pas la façon dont elles fonctionnent, parce que le faire de cette façon conduit à d'énormes problèmes d'interopérabilité. C'est pourquoi les spécifications web modernes visent à spécifier entièrement tous les comportements. Si vous voyez un cas où le comportement semble ne pas être spécifié, alors soit la spécification est boguée, soit vous la lisez mal (et elle peut toujours être boguée parce qu'elle peut être mal lue).
2 votes
@BorisZbarsky : L'objectif de la définition de la syntaxe et des critères de conformité est de dire "Si votre matériel ressemble à ceci, les implémentations le comprendront. Si ce n'est pas le cas, nous ne pouvons pas garantir les résultats souhaités." La deuxième phrase est ce qui fait que la première phrase vaut la peine d'être dite. Une spécification linguistique ne peut pas imposer un comportement (autre que "considérer que le contenu n'est pas $LANGUAGE") pour chaque cas non conforme. C'est bien en dehors de son champ d'application, et essayer de le faire le transforme en une spécification UA - et dans le cas de HTML, rendrait la validité du langage lui-même complètement non pertinente.
1 votes
Les "énormes problèmes d'interopérabilité" dus à un HTML invalide étaient/sont dus au fait que le document ne se conforme pas aux règles du langage qu'il prétend utiliser. Des déchets à l'entrée, des déchets à la sortie. Les règles ne sont pas secrètes ; les plus importantes ne sont même pas compliquées. Il n'y a aucune excuse pour les enfreindre, et la dernière chose qu'une spécification de langage digne de ce nom devrait faire est de en soutenant ladite rupture.
4 votes
@cHao Non, le but de la définition des spécifications web est de s'assurer de l'interopérabilité. La définition de la syntaxe est en grande partie là pour que vous puissiez définir des points d'extensibilité clairs. Les spécifications CSS visent à imposer un comportement pour tout contenu non conforme, comme le fait HTML, et ce depuis des années. Et les "problèmes d'interopérabilité" dont je parle n'étaient pas dus à du HTML invalide mais plutôt à des problèmes de CSS, soit parce que les UA n'ont pas réussi à mettre en œuvre correctement les exigences de la spécification parce qu'elles ont lu entre les lignes, soit parce que la spécification appelle explicitement des choses non définies et qu'elles sont ensuite forcées de spécifier des absurdités mises en œuvre par les UA et supposées par les sites.
0 votes
Quoi qu'il en soit, l'autre confusion ici est que le but premier des spécifications CSS est en fait d'être une spécification UA, et non une spécification de langage. L'autre a été essayée, et a échoué.
1 votes
@BorisZbarsky : Le fait que l'on puisse même puede lire entre les lignes signifie que la spécification ne couvre pas tous les cas . Les auteurs de la spécification ont soit délibérément évité de le faire, soit échoué lamentablement. (Je suppose que c'est le premier cas, car (1) toutes les preuves disponibles pointent dans cette direction, nonobstant vos déclarations d'intention aux auteurs, et (2) ce ne sont pas des idiots. :P) Quoi qu'il en soit, une lecture littérale des spécifications laisse une part non négligeable de comportement d'erreur non spécifié. Et une lecture littérale est la seule option lorsque vous essayez de comprendre ce qui est réellement requis dans ces cas.
1 votes
Pour ce qui est de la définition de la syntaxe, de la sémantique, etc., si vous avez raison, tout cela est sans intérêt. Je peux écrire une soupe de tags et la faire fonctionner de manière tout aussi fiable à tout moment. Pourquoi se soucier de la conformité du HTML ?
2 votes
Pourquoi s'en soucier ? Si tout ce qui vous importe est l'aspect visuel des UA, il n'y a aucune raison ; c'est pourquoi presque personne ne s'en soucie dans la pratique. Si vous voulez que votre HTML soit plus facile à maintenir et plus significatif d'un point de vue sémantique, et peut-être plus rapide à rendre, il peut y avoir des raisons de s'en soucier.
7 votes
Je ne suis même pas sûr que quelqu'un d'autre que vous deux puisse comprendre ce qui se passe avec cette longue conversation. Nous avons un chat pour ces longues discussions. Tout ce que vous voulez vraiment garder en mémoire devrait être mis dans la question ou dans une réponse, surtout s'il s'agit d'une information de clarification. Stack Overflow ne gère pas bien les discussions dans les commentaires.
1 votes
Je peux, et je peux dire que la plupart de ce qui a été discuté n'appartient pas à SO mais à une liste de diffusion.
2 votes
J'aurais peut-être dû faire un commentaire plus tôt, mais c'est très simple : soit vous respectez les règles, soit vous risquez des incohérences entre les navigateurs. C'est tout ce qu'il y a à faire. Si vous vous dites "Je me moque des règles, car cela ressemble à ce que je veux dans le navigateur", c'est que vous n'avez pas testé suffisamment de navigateurs. Si vous avez des ID en double dans votre HTML, différents navigateurs renverront des résultats différents. Regardez ce document avec IE, Edge, Chrome, Firefox. J'en reste là.
0 votes
Dans ce fil de discussion, nous avons vu des démons nasaux littéralement sortir du nez des gens.