599 votes

Pourquoi les navigateurs font-ils correspondre les sélecteurs CSS de droite à gauche ?

Les moteurs de navigation font correspondre les sélecteurs CSS de droite à gauche. Ils trouvent donc d'abord les enfants, puis vérifient leurs parents pour voir s'ils correspondent au reste des éléments de la règle.

  1. Pourquoi ?
  2. C'est juste parce que les spécifications le disent ?
  3. Cela affecte-t-il la mise en page finale si elle a été évaluée de gauche à droite ?

Selon moi, le plus simple serait d'utiliser les sélecteurs comportant le moins d'éléments possible. Donc les ID en premier (puisqu'ils ne devraient renvoyer qu'un seul élément). Ensuite, peut-être les classes ou un élément qui a le moins de noeuds - par exemple, il peut n'y avoir qu'un seul span sur la page, donc aller directement à ce noeud avec toute règle qui fait référence à un span.

Voici quelques liens qui confirment mes affirmations

  1. http://code.google.com/speed/page-speed/docs/rendering.html
  2. https://developer.mozilla.org/en/Writing_Efficient_CSS

Il semble que cela soit fait de cette façon pour éviter d'avoir à regarder tous les enfants du parent (qui pourraient être nombreux) plutôt que tous les parents d'un enfant qui doit être unique. Même si le DOM est profond, il ne regarderait qu'un nœud par niveau plutôt que plusieurs dans la correspondance RTL. Est-il plus facile/rapide d'évaluer les sélecteurs CSS LTR ou RTL ?

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 ?

860voto

Boris Zbarsky Points 22158

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

En prime, il est plus logique de le lire en RTL qu'en LTR, même en anglais. Un exemple : stackoverflow.com/questions/3851635/css-combinator-precedence/

8 votes

Notez que la correspondance RTL ne s'applique qu'aux combinateurs . Il ne va pas jusqu'au niveau du simple sélecteur. En d'autres termes, un navigateur prend la sélection la plus à droite sélecteur de composés ou séquence de sélecteurs simples et tente de le faire correspondre de manière atomique. Ensuite, s'il y a une correspondance, il suit le combinateur vers la gauche jusqu'à l'élément sélecteur de composé suivant et vérifie l'élément à cette position, et ainsi de suite. Rien ne prouve qu'un navigateur lise chaque partie d'un sélecteur composé RTL ; en fait, le dernier paragraphe montre précisément le contraire (les vérifications d'id viennent toujours en premier).

5 votes

En fait, au moment où vous faites correspondre les sélecteurs, au moins dans Gecko, le nom de domaine et l'espace de nom viennent en premier. L'id (ainsi que le tagname et les noms de classe) est pris en compte dans une étape de pré-filtrage qui élimine la plupart des règles sans vraiment essayer de faire correspondre les sélecteurs.

39voto

aWebDeveloper Points 5546

L'analyse syntaxique de droite à gauche, également appelée analyse ascendante est en fait efficace pour le navigateur.

Considérez ce qui suit :

#menu ul li a { color: #00f; }

Le navigateur vérifie d'abord si a entonces li entonces ul et ensuite #menu .

En effet, lorsque le navigateur scanne la page, il n'a besoin que de regarder l'élément/nœud actuel et tous les nœuds/éléments précédents qu'il a scannés.

Ce qu'il faut noter, c'est que le le navigateur commence le traitement dès qu'il reçoit une balise/nœud complète et n'a pas besoin d'attendre toute la page sauf quand il trouve un script, auquel cas il fait une pause temporaire et termine l'exécution du script puis continue.

S'il fait l'inverse, il sera inefficace car le navigateur a trouvé l'élément qu'il analysait lors de la première vérification, mais il a ensuite été obligé de continuer à chercher dans le document tous les sélecteurs supplémentaires. Pour cela, le navigateur doit disposer de l'ensemble du code html et peut avoir besoin de scanner toute la page avant de commencer à peindre les css.

C'est contraire à la façon dont la plupart des librairies analysent les domaines. Là, le dom est construit et il n'a pas besoin de scanner toute la page, juste de trouver le premier élément et ensuite de faire correspondre les autres à l'intérieur.

21voto

Gregory A Beamer Points 10975

Il permet de passer en cascade du plus spécifique au moins spécifique. Elle permet également un court-circuit dans l'application. Si la règle plus spécifique s'applique à tous les aspects auxquels la règle parente s'applique, toutes les règles parentes sont ignorées. Si le parent contient d'autres éléments, ils sont appliqués.

Dans l'autre sens, il faudrait formater en fonction du parent et écraser chaque fois que l'enfant a quelque chose de différent. À long terme, cela représente beaucoup plus de travail que d'ignorer des éléments dans des règles qui sont déjà prises en charge.

11 votes

C'est une question distincte. Vous effectuez la mise en cascade en triant les règles par spécificité, puis en les faisant correspondre par ordre de spécificité. Mais la question ici est de savoir pourquoi, pour une règle donnée, vous faites correspondre ses sélecteurs d'une manière particulière.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X