5139 sujets

Le Bar du forum

Coup de gueule éclair sur cette syntaxe fielleuse du nth-child & co.

J'veux dire,

nth-child(2), j'ai mon premier élément, jusque là okay.
Mais... nth-child(n2), nth-child(2n), nth-child(4n+3), nth-child(4n-3)... what ?! Oo

Réfléchissons,
"N" c'est pour "number" j'imagine, donc :
nth-child(n2) signifie "nombre deux". Uniquement le 2 ?
nth-child(2n) "deux nombres", 1 & 2 ?
nth-child(2n+3) "deux nombres plus trois", 4 & 5 ?
nth-child(1n2), nth-child(4n-3)... ah ben non en fait. Ça doit pas marcher comme ça.

Non franchement, sans mauvaise foi, n'y avait-il pas 20.000 autres syntaxes possibles plus logiques pour ce sélecteur ?
nth-child(1) pour le premier élément hein Smiley smile

nth-child(3n+0) = tous les 3 elements, nth-child(3n)
nth-child(3n+1) = tous les 3 elements, en partant du premier,
nth-child(n5) ne fonctionne pas
nth-child(n + 5) = à partir du 5eme elements.

je sais pas si d'autre syntaxe serait plus logique, elle est très clair pour moi. Peut être dois-tu la travailler encore un peu Smiley smile
Modifié par JENCAL (24 Nov 2015 - 12:39)
Modérateur
Bonjour bonjour,

En fait on y reconnait les maths comme les équations de droite : f(x) = ax + b

MDN a écrit :
La pseudo-classe CSS :nth-child(an+b) cible un élément qui a an+b-1 nœuds frères, pour une valeur de n positive ou égale à 0, et qui a un élément parent.

Ceci peut être décrit de manière plus claire : l'élément ciblé, est le bème enfant d'un élément, après que tous ses enfants aient été découpés en goupe de a éléments chacun.

Les valeurs a et b doivent être des nombres entiers, et l'index du premier enfant d'un élément est 1.

En d'autre mots, cette pseudo-classe cible tous les enfants dont l'index tombe dans le set { an + b; n = 0, 1, 2, ... }.


C'est assez bien expliqué ici : https://developer.mozilla.org/fr/docs/Web/CSS/%3Anth-child

nth-child(2) sélectionne le 2nd élément.
nth-child(2n) sélectionne les élément pour n de 0 à l'infini pour la formule 2n soit : 2x0=0 , 2x1=2, 2x2=4 , ... etc donc tout les éléments pairs.
nth-child(2n+3) sélectionne les élément pour n de 0 à l'infini pour la formule 2n+3 soit : 2x0+3=3 , 2x1+3=5 , 2x2+3=7 , etc donc les éléments pairs (comme au dessus) mais décalé de 3.

Est-ce un peu plus clair ?
Modifié par _laurent (24 Nov 2015 - 12:20)
Du coup ce qui n'est pas très logique c'est que la numérotation commence à 1. Soit a et b des nombres, et soit notre élément de référence ayant moins de 2a enfants, le raccourci nth-child(a) devrait être équivalent à nth-child(a+0) ou nth-child(n+a) (équivalent dans le sens matcher la même chose). Si on suit la même logique jusqu'au bout, c'est nth-child(0) qui devrait être équivalent à first-child et non pas nth-child(1).

Ou alors la notation "an+b" devrait tenir compte du fait que la numérotation commence à 1 et non 0 et ainsi "2n+1" devrait prendre le premier, le troisième, le cinquième, etc. et non pas le deuxième, le quatriième, le sixième, etc.
Mais alors dans ce cas ce n'est pas du tout intuitif.

Soit on applique une logique informatique/mathématique partout, soit on ne l'applique nulle part ! Mélanger une logique commençant à 0 et une autre commençant à 1 est le meilleur moyen de se planter bêtement.

Question bonus à laquelle je ne connais pas la réponse: peut-on utiliser des nombres négatifs ?
Dans ce cas on aurait les correspondances suivantes :
- nth-child(-1) serait équivalent à last-child,
- nth-child(n-2) prendrait tout sauf le dernier,
- ou, plus tordu, - nth-child(-2n-1) serait équivalent à nth-child(2n+0) ou nth-child(2n+1) selon qu'il y a un nombre pair ou impair d'enfants; le point de repère c'est qu'on ne veut pas que le dernier soit matché.
Modifié par QuentinC (24 Nov 2015 - 13:50)
Modérateur
QuentinC a écrit :
Ou alors la notation "an+b" devrait tenir compte du fait que la numérotation commence à 1 et non 0 et ainsi "2n+1" devrait prendre le premier, le troisième, le cinquième, etc. et non pas le deuxième, le quatriième, le sixième, etc.

Heu... ben c'est le cas...
2x0+1 = 1
2x1+1 = 3
2x2+1 = 5
...
https://jsfiddle.net/mvkqva6c/2/

QuentinC a écrit :
Mais alors dans ce cas ce n'est pas du tout intuitif.

Ça c'est un autre soucis. Je sais pas si c'est moins intuitif que de commencer à 0 mais c'est déroutant si on a l'habitude de travailler avec des tableaux ou objets...

QuentinC a écrit :
Question bonus à laquelle je ne connais pas la réponse: peut-on utiliser des nombres négatifs ?

Ouep : http://nthmaster.com/
Enfin pas totalement. On peut utiliser un sélecteur d’adjacence négative mais pas un nombre final négatif. Voyons avec tes exemples :
QuentinC a écrit :

- nth-child(-1) serait équivalent à last-child,
- nth-child(n-2) prendrait tout sauf le dernier,
- ou, plus tordu, - nth-child(-2n-1) serait équivalent à nth-child(2n+0) ou nth-child(2n+1) selon qu'il y a un nombre pair ou impair d'enfants; le point de repère c'est qu'on ne veut pas que le dernier soit matché.

Là je crois que tu t'emballe un peu...

nth-child(-1) ne fonctionne pas car il faut un nombre positif. S'il marchait, il sélectionnerait l'élément -1 dans la liste. Rien a voir avec last-child, ce n'est pas une boucle. C'est juste qu'avant l'élément 1 bah il n'y a rien (il n'y a pas la fin de sa propre liste, comme au dessus de ta tete il n'y a pas tes pieds ! Smiley langue )

nth-child(n-2) fonctionne lui. Mais il suit la meme logique que les autres :
1x0-2 = -2 (ne sélectionne rien car n'existe pas)
1x1-2 = -1 (ne sélectionne rien car n'existe pas)
1x2-2 = 0 (ne sélectionne rien car n'existe pas)
1x3-2 = 1 (sectionne l’élément 1)
1x4-2 = 2 (sectionne l’élément 2)
Donc la formule nth-child(n-2) est un peu useless car elle correspond a nth-child(n) qui sélectionne tout...

nth-child(-2n-1) part d'un négatif (-1) et s'en va dans les négatifs donc il ne sélectionnera jamais rien.

Le cas d'utilisation des nombres n'égatifs peut être le suivant (partir d'un élément et remonter) :
:nth-child(-n+9) cf le lien de tout a l'heure http://nthmaster.com/
-1x0+9=9
-1x1+9=8
-1x2+9=7
-1x3+9=6
etc

Et on peut même les combiner pour n'en prendre qu'une partie (cf toujours le même lien)
Modifié par _laurent (24 Nov 2015 - 14:45)
Merci à tous pour vos réponses, c'est plus clair (un peu).
Et même si ca me rassure de voir qu'ils ont basé leur logique sur un truc déjà existant, ca reste quand même inutilement compliqué pour moi.
Chui allé voir "Équation de droite" sur wiki, je me suis fais peur. xD

NB : Oui j'avais fais une faute de frappe au début et je savais que mes exemples étaient erronés, c'était pour démontrer le raisonnement que j'avais eu quand j'avais commencé à utiliser les nth-x.

Pour résumer :

n signifie qu'on veut plusieurs enfants à partir d'un point donné.
-n l'inverse, jusqu'au point donné.
+X permet de décaler ce point donné. On peut également virer le "+".
Xn permet de spécifier un espacement d'enfant sélectionné.

Donc :

n = 1n c'est bien ça ?
0n lui = "rien" (juste le nombre)

Et si on veut partir de la fin, faut faire quoi ?

Et du coup pourquoi "2n+3" et "2n-3" me donnent deux résultats différents ?
C'est censé faire quoi "n-X" ?

Sinon, il y a ce site qui permet de tester également :
http://nth-test.com/
Modérateur
En fait met toi dans la tête que "n" ça représente tout les nombres entiers de 0 à l'infini (0, 1, 2, 3 ...).

Quand tu lui donne une formule il va calculer le résultat comme je l'ai fait à chaque fois au dessus pour chaque valeur de n.

Donc "n" les résultats seront égaux à "1 puis 2 puis 3 puis 4 ..." (l'élément 0 n'existant pas)
Pour "2n" les résultats seront égaux à "2 puis 4 puis 6" (l'élément 0 n'existant pas)

Il suffit juste de remplacer n par 0 puis 1 puis 2 puis 3 puis 4 etc...

C@scou a écrit :
n = 1n c'est bien ça ?
0n lui = "rien" (juste le nombre)

C'est bien ça mais il faut continuer pour toutes les valeurs de n

C@scou a écrit :
Et du coup pourquoi "2n+3" et "2n-3" me donnent deux résultats différents ?

Donc (je ne fait que remplacer les n par les nombres 0, 1, 2... hein) :
2n+3 correspondra à 2x0+3= 3 puis 2x1+3= 5 ...
2n-3 correspondra à 2x0-3= -3 (n'existe pas) puis 2x1-3= -1 (n'existe pas) puis 2x2-3= 1 ...

le +X permet comme tu le dis de décaler le départ.
2N a commencé a 2 alors que 2N+3 à commencé à 5 (décalé de 3).

le Yn quand a lui va déterminé l'espacement comme tu as dit. 2n prendra 1 élément sur 2 (le 2, le 4, le 6 etc...)
Modifié par _laurent (24 Nov 2015 - 16:00)
Modérateur
Et pour partir de la fin tu peux check nth-last-child() qui marche pareil mais depuis la fin (ton dernier élément c'est le 1, ton avant dernier le 2 etc...)

:nth-child(-n+3) sélectionne les 3 premiers éléments donc :nth-last-child(-n+3) sélectionnera les 3 derniers.

Si tu as un besoin de sélectionner proprement des éléments et que ça coince, poste une nouveau sujet avec un exemple concret (HTML + CSS) Smiley smile
a écrit :
Heu... ben c'est le cas...
2x0+1 = 1
2x1+1 = 3
2x2+1 = 5
...
https://jsfiddle.net/mvkqva6c/2/


Au temps pour moi, je n'avais pas testé et d'après ce que l'auteur disait, ça n'avait pas l'air d'être le cas. La totalité de la numérotation se base donc sur 1, il n'y a donc pas d'incohérence et j'ai partiellement dit de la merde. Désolé.

Ca reste pas très logique d'après moi, mais c'est tout à fait cohérent.

a écrit :
nth-child(-1) ne fonctionne pas car il faut un nombre positif. S'il marchait, il sélectionnerait l'élément -1 dans la liste. Rien a voir avec last-child, ce n'est pas une boucle. C'est juste qu'avant l'élément 1 bah il n'y a rien (il n'y a pas la fin de sa propre liste, comme au dessus de ta tete il n'y a pas tes pieds !


Bah, c'était pas forcément con comme idée. Dans un certain nombre de langages, -1 indique le dernier élément d'une liste; en python par exemple.
Bon bref ça marche pas comme ça, du coup j'ai embrouillé tout le monde.

En fait si on veut un élément sur deux et pas le dernier, le plus simple c'est nth-child(-n+2) alors.

Par contre, je suis le seul à relever pour odd et even ? C'est un raccourci bien pratique.
Modifié par QuentinC (24 Nov 2015 - 17:10)
Modérateur
QuentinC a écrit :
En fait si on veut un élément sur deux et pas le dernier, le plus simple c'est nth-child(-n+2) alors.

Hehehe je sais pas si tu t'es loupé en ecrivant ou si tu t'es encore vautré ( Smiley lol taquinage) mais :nth-child(-n+2) sélectionne les deux premiers éléments...
-1x0 + 2 = 2
-1x1 + 2 = 1
-1x2 + 2 = 0
-1x3 + 2 = -1
...

Si tu veux "un élément sur deux et pas le dernier" dans le sens "un élément sur deux en partant de la fin et sans prendre le premier c'est :nth-last-child(2n+2)

Si c'est dans le sens "un élément sur deux en partant du début mais pas le dernier (demande un peu tordue dans le cadre d'un nombre d'élément impaire)" là il faut combiner deux trucs :nth-child(2n+1):nth-last-child(n+2) https://jsfiddle.net/mvkqva6c/3/

Il suffit de tester (même juste mentalement avec 0 et 1 voir 2, c'est easy et ca donne la direction) avant de poster Smiley lol

QuentinC a écrit :
Par contre, je suis le seul à relever pour odd et even ? C'est un raccourci bien pratique.

Et oui effectivement odd et even sont bien pratiques pour remplacer 2n ou 2n+1 mais bon le besoin n'était pas sur le tapis (et comme tout raccourcis, c'est à utiliser quand on maîtrise la route normale !! Smiley lol #pastaper #pastaper)


QuentinC a écrit :
Bah, c'était pas forcément con comme idée. Dans un certain nombre de langages, -1 indique le dernier élément d'une liste; en python par exemple.

Je connais pas bien le python et c'est vrai que c'est pas une mauvaise idée et ça à l'air plutôt pratique Smiley smile

Bonne soirée !

Bisous
Modifié par _laurent (24 Nov 2015 - 22:27)
a écrit :
Hehehe je sais pas si tu t'es loupé en ecrivant ou si tu t'es encore vautré (


Non je me suis bel et bien encore vautré Smiley lol

C'est l'existance de nth-last-child que je n'ai pas relevée hier.

Bref; un peu tordu au début, mais au final, assez simple une fois qu'on a pigé le truc
a écrit :
Par contre, je suis le seul à relever pour odd et even ? C'est un raccourci bien pratique.

Nonon. J'utilise tout le temps odd & even. ^^

C'est d'ailleurs un peu pour ça que moi la valeur précédant le "n" m'a toujours un peu gonflé.
Je ne l'utilise pas pour ça.

a écrit :
comme tout raccourcis, c'est à utiliser quand on maîtrise la route normale

Oui mais ca serait quand même con de se priver d'une route en goudron sous prétexte que la route en terre est plus large. xD

En fait, si j'ai bien pigé tes conversions en équation, "n" c'est la valeur itérée ?
Et vu que du coup en math (ca viens de me revenir) un chiffre suivit d'une lettre sous-tend une multiplication...

a écrit :
nth-last-child

C'est typiquement le genre de truc que je n'utilise pas assez souvent pour m'en souvenir et que régulièrement soi j'oublie d'utiliser (et je me complique la vie) soi je cherche pendant 10 minutes sur le web comment c'était ce p*tain de truc trop bien. Smiley langue

a écrit :
Bref; un peu tordu au début, mais au final, assez simple une fois qu'on a pigé le truc

C'est pas faux.