Jouons avec les pseudos-classes des sélecteurs css
Ça fait quelques temps (depuis la sortie de firefox 3.5, en fait) que j'avais envie de jouer avec quelques sélecteurs css issus de la version 3 de la norme. En fait, nous allons nous amuser avec quelques pseudos-classes. Pour les cancres, les pseudos-classes sont un mécanisme de css qui permet de sélectionner des éléments selon des critères qui ne sont pas explicitements contenus dans de document.
a:hover { … } /* Ça vous dit quelque chose ? */
Voici donc notre élément html de travail, un joli (ou pas) tableau tout ce qu'il y a de plus classique :
riri | fifi | loulou |
moutarde | mayo | ketchup |
git | cvs | svn |
linus | richard | eric |
html | css | php |
symfony | cake | pluf |
Et le code associé :
<table> <tr> <td>riri</td> <td>fifi</td> <td>loulou</td> </tr> <tr> <td>moutarde</td> <td>mayo</td> <td>ketchup</td> </tr> <tr> <td>git</td> <td>cvs</td> <td>svn</td> </tr> <tr> <td>linus</td> <td>richard</td> <td>eric</td> </tr> <tr> <td>html</td> <td>css</td> <td>php</td> </tr> <tr> <td>symfony</td> <td>cake</td> <td>pluf</td> </tr> </table>
nth-child et nth-last-child
Notre premier sélecteur porte le doux nom de nth-child. Son utilité ? Il permet de styler des éléments choisis selon leur index dans des groupes. Un exemple sera beaucoup plus parlant.
Imaginons que je veuille affecter une couleur de fond à toutes les lignes impaires de mon tableau (ce que est un besoin assez courant). Et pour pousser le vice, je souhaite aussi mettre en gras une ligne sur trois à partir de la deuxième (ça, c'est déjè moins courant).
Et bien surprise, je vais faire ça très simplement :
table tr:nth-child(2n+1) { background-color: #f0f0f0; } table tr:nth-child(3n+2) { font-weight: bold; }
La syntaxe «nth-child(an+b)» signifie qu'on sélectionne l'élément numéro «b» dans chaque groupe de «a» éléments par rapport à un parent commun. Quand au sélecteur nth-last-child, il fonctionne exactement de la même façon, excepté le fait que le comptage des éléments se fait de bas en haut dans le document (c'est clair ?).
Et le résultat :
riri | fifi | loulou |
moutarde | mayo | ketchup |
git | cvs | svn |
linus | richard | eric |
html | css | php |
symfony | cake | pluf |
Pas mal, non ? Comment, vous ne voyez pas la différence ? Et bien, c'est parce que votre navigateur ne gère pas les sélecteurs avancés. Il serait peut-être temps d'utiliser un vrai navigateur ?
Ici, nous avons pris un tableau pour exemple, mais on pourrait styler un commentaire sur deux dans un blog, ou imaginer des choses beaucoup plus tordues. Par exemple, on pourait affecter 5 couleurs successives à tous les paragraphes de la page :
p:nth-child(5n+1) { background-color: blue; } p:nth-child(5n+2) { background-color: red; } p:nth-child(5n+3) { background-color: yellow; } /* … */
Ah ! Et au fait :
tr:nth-child(2n+1) /* peut être raccourci en */ tr:nth-child(odd) /* et */ tr:nth-child(2n) /* est équivalent à */ tr:nth-child(even)
nth-of-type, nth-last-of-type
Le sélecteur nth-of-type ressemble à nth-child, sauf qu'on ne prends en compte que les éléments de même type pour effectuer les groupes. Quand à nth-last-of-type, vous aurez deviné à quoi il sert. Là encore, un exemple sera plus parlant.
Admettons que mon article contienne des images d'illustrations. Je veux aligner successivement les images à droite, puis à gauche, et ce automatiquement, dans la mesure où je suis un fainéant.
#article img:nth-of-type(odd) { float: right; } #article img:nth-of-type(even) { float: left; }
Et le résultat :
Alors !? Hein ?! C'est-y-pas beau ?!? Moi, en tout cas, ça m'émerveille toujours autant (oui, je suis sensible).
first-child et last-child
Ça, c'est facile. first-child permet de sélectionner le premier parmi une liste d'éléments. Et last-child, je vous laisse deviner ce que c'est.
Petit exemple facile :
table tr:first-child, table tr:last-child { background-color: #f0f0f0; }
Et que voit-on apparaitre devant nos yeux ébahis ???
riri | fifi | loulou | loulou |
moutarde | mayo | ketchup | loulou |
git | cvs | svn | loulou |
linus | richard | eric | loulou |
html | css | php | loulou |
symfony | cake | pluf | loulou |
first-of-type, last-of-type
Les sélecteurs first-of-type et last-of-type permettent respectivement de sélectionner le premier et le dernier parmi les frères de l'élément. Comme d'hab' un petit exemple :
td:first-of-type { padding-left: 100px ; } td:last-of-type { padding-right: 100px; }
Ici, nous sélectionnons les premiers et derniers éléments «td» de chaque ligne et on leur applique un padding particulier. Le résultat :
riri | fifi | loulou | loulou |
moutarde | mayo | ketchup | loulou |
git | cvs | svn | loulou |
linus | richard | eric | loulou |
html | css | php | loulou |
symfony | cake | pluf | loulou |
symfony | cake | pluf | loulou |
only-child, only-of-type
Le sélecteur only-child désigne un élément qui n'as pas de frères dans l'arbo. only-of-type désigne un élément qui n'a pas de frères du même type que lui.
<ul> <li>test</li> <li>test</li> <li>test</li> <li>test</li> </ul> <ul> <li>test</li> </ul> <ul> <li>test</li> <li>test</li> </ul>
li:only-of-type { font-weight: bold; background-color: lime; }
- test
- test
- test
- test
- test
- test
- test
not
not(X) permet de sélectionner les éléments qui ne correspondent pas au sélecteur passé en paramètre.
li:not(:only-of-type) { font-weight: bold; background-color: lime; }
- test
- test
- test
- test
- test
- test
- test
Conclusions et références
Bien entendu, tous les sélecteurs peuvent dans une certaine mesure être combinés pour créer des expressions puissantes (tordues). Autre évidence, l'intérêt de la chose reste somme toutes assez limités à cause du support navrant des sélecteurs css3 de la part d'un certain navigateur.
Pour finir, pour les curieux, je vous dirige vers les références qui ont servi de base à cet article.