Apprendre à utiliser les Sélecteurs en CSS
#1 Prérequis
Pour pouvoir faire ce tutoriel, il faut connaître les bases de la sélection CSS. Si ce n'est pas votre cas, je vous renvoie au tutoriel Débuter en CSS dans lequel vous trouverez des éléments de base concernant la syntaxe des règles CSS et le principe des sélecteurs.
#2 Les règles de nommage des identificateurs et des classes
On appelle identifiant le nom d'un identificateur ou le nom d'une classe. Lorsqu'un programmeur crée un identifiant, il doit respecter des règles. En CSS, les identifiants ne peuvent contenir que des lettres (minuscules ou majuscules) ou des chiffres [a-zA-Z0-9] avec en plus le trait d'union et le tiret bas (underscore).
Il y a des contraintes spécifiques pour la première lettre, voire les deux selon les cas. Les identifiants ne peuvent pas commencer par un chiffre, deux underscore ou un underscore suivi d'un chiffre ou un trait d'union suivi d'un chiffre.
Le plus simple est de systématiquement commencer par une lettre et vous n'aurez pas de problème.
Souvenez-vous également que le CSS est sensible à la case pour les noms des identifiants. La classe para
ne sera pas identique à la classe PARA
. C'est pareil pour un identificateur.
Par contre, le CSS n'est pas case sensitive pour les noms des balises HTML, les noms et les valeurs des propriétés CSS.
#3 Sélecteur universel. * {...}
Le sélecteur universel est utilisé pour sélectionner tous les éléments du document. Il est souvent utilisé pour faire ce que l'on appelle un reset CSS. C'est la règle CSS que vous pouvez voir dans l'exemple ci-dessous. Cette règle figure souvent au début de la feuille de style. Tous les éléments sont sélectionnés de manière à mettre à zéro les margin et les padding qui proviennent de la feuille de style par défaut d'un navigateur.
Il faut savoir, que le reset CSS est controversé, car justement, il sélectionne tous les éléments sans aucune distinction. Je vous le montre donc ici à titre d'exemple sans forcément vous le conseiller.
Tester le code#4 Sélection d'un identificateur. #mon-id {...}
Dans l'exemple ci-dessous, je sélectionne le paragraphe qui est repéré par l'identificateur para
et pour cela, je mets un dièse (# hashtag) devant para
au niveau du sélecteur qui est donc #para
. Je ne sélectionne que ce paragraphe et strictement rien d'autre.
J'en profite pour vous rappeler qu'un identificateur doit être unique dans un document, car sinon, il y a une ambiguïté au niveau de l'identification d'un et d'un seul élément 😇.
Tester le code#5 Sélection d'une classe. .ma-classe {...}
Ci-dessous, je sélectionne deux éléments HTML différents au moyen d'une classe. Ici, la classe para
. Pour cela, au niveau du sélecteur CSS, j'écris le nom de la classe, soit para
, et je mets un point devant, soit .para
. Comprenez bien, qu'il n'est pas obligatoire que les éléments HTML soient différents. C'est possible et c'est ce que j'ai voulu montrer dans l'exemple ci-dessous, mais ce n'est pas obligatoire.
#6 Sélection d'éléments HTML. h2 {...}
Dans l'exemple ci-dessous, je sélectionne tous les éléments h2
. Curieusement, à mon goût, ce sélecteur est appelé le sélecteur de type. C'est sans doute parce qu'il sélectionne tous les éléments de "type" h2. Mais le "type" d'un élément HTML ça peut être une façon de parler, mais ça ne veut rien dire de précis. Bon, c'est l'idée.
Il est possible de coupler le sélecteur de type avec le nom d'un identifiant p#para
ou d'une classe p.para
. Personnellement, je trouve que cette façon d'écrire améliore la lisibilité de la feuille de style. Toutefois, attention, car ça change la spécificité du sélecteur. Si vous ne savez pas ce qu'est la spécificité d'un sélecteur, je vous conseille le tuto sur la cascade CSS.
#7 Sélecteur multiple. h2 , #para {...}
Il s'agit en fait d'utiliser plusieurs sélecteurs qui vont appliquer le même bloc de déclarations. Pour cela, il faut séparer chaque sélecteur par une virgule. Dans l'exemple ci-dessous, je cible d'abord tous les éléments h2
puis, le paragraphe d'identificateur para
. Je dis tous les éléments h2
, car, s'il y avait plusieurs éléments h2
le sélecteur les sélectionnerait tous. Dans mon exemple, il n'y a qu'un seul élément h2
et dans ce cas, en les prenant tous, je ne vais prendre que celui-là.
#8 Sélection avec un attribut HTML. img[title] {...}
Dans l'exemple suivant, j'ai positionné des images avec différentes valeurs, pour l'attribut title
. J'ai pris title
, et pas alt
, pour avoir une info bulle au survol d'une image par le curseur de la souris. De cette manière, on comprend facilement, en survolant l'image, pourquoi elle a été sélectionnée ou pas.
On va tester tous les cas de figures pour la recherche du mot Paris
dans cet attribut title
. Ci-dessous, vous avez le code HTML de base, dans lequel je vais modifier la règle CSS de manière justement à tester tous ces cas de figures.
Dans le code HTML de base ci-dessus, j'édite la règle CSS, de manière à avoir, la règle CSS ci-dessous. Avec le sélecteur ci-dessous, je vais sélectionner tous les éléments dans lesquels l'attribut title existe. Comprenez bien, c'est un test sur sa présence, et pas un test sur sa valeur. Si vous regardez le code HTML de base, il n'y a que dans la dernière image paris-sacre-coeur.jpg
que l'attribut title
n'est pas présent. Donc, la dernière image sera la seule image à ne pas avoir de cadre marron-rouge.
Dans mon code HTML de base, je modifie la règle CSS, de manière à avoir, la règle CSS ci-dessous. Avec le sélecteur ci-dessous, je vais sélectionner tous les éléments, dans lesquels l'attribut title
a exactement la valeur Paris
. Quand je dis exactement, ça veut dire qu'il ne doit rien avoir, ni devant ni derrière le mot Paris
et qu'en plus le P
de Paris
doit être un P
majuscule et les autres lettres des minuscules. Dans ce cas, on dit que la comparaison est case sensitive ou sensible à la case. Si vous regardez le code HTML de base, vous constatez qu'il n'y a que l'image paris-trocadero.jpg
qui répond au sélecteur. Ce sera donc la seule image qui aura un cadre marron-rouge.
Dans mon code HTML de base, je modifie la règle CSS, de manière à avoir, la règle CSS ci-dessous. Avec le sélecteur ci-dessous, je vais sélectionner tous les éléments dans lesquels l'attribut title
contient au moins une occurrence du mot Paris
. Quand je dis contient au moins une occurrence du mot, ça veut dire qu'il peut y avoir d'autres mots devant ou derrière le mot Paris
. Il s'agit du mot Paris
à la majuscule près. Si vous regardez le code HTML de base, vous constatez qu'il y a l'image paris-notre-dame.jpg
puis paris-seine.jpg
puis paris-eiffel.jpg
et enfin paris-trocadero.jpg
qui sont dans ce cas. Ces images auront donc un cadre marron-rouge.
Dans mon code HTML de base, je modifie la règle CSS, de manière à avoir, la règle CSS ci-dessous. Avec le sélecteur ci-dessous, je vais sélectionner tous les éléments dans lesquels l'attribut title
commence par le mot Paris
. Quand je dis commence, ça veut dire qu'il peut y avoir d'autres mots derrière le mot Paris
. Il s'agit du mot Paris
à la majuscule près. Si vous regardez le code HTML de base, vous constatez qu'il y a l'image paris-seine.jpg
et paris-trocadero.jpg
qui sont dans ce cas. Ces images auront donc un cadre marron-rouge.
Dans mon code HTML de base, je modifie la règle CSS, de manière à avoir, la règle CSS ci-dessous. Avec le sélecteur ci-dessous, je vais sélectionner tous les éléments dans lesquels l'attribut title
se termine par le mot Paris
. Quand je dis se termine, ça veut dire qu'il peut y avoir d'autres mots devant le mot Paris
. Il s'agit du mot Paris
à la majuscule près. Si vous regardez le code HTML de base, vous constatez qu'il y a l'image paris-eiffel.jpg
et paris-trocadero.jpg
qui sont dans ce cas. Ces images auront donc un cadre marron-rouge.
#9 Combinateur de descendants. #dialog-connexion .push_button {...}
Les combinateurs vous aident à vous positionner sur l'arborescence du document en utilisant les relations ancêtre et descendant, parent et enfant, frère. Qu'est-ce que ça veut dire ? Un élément HTML peut contenir un autre élément HTML. L'élément "qui contient" est l'élément parent. L'élément qui "est contenu" est l'élément enfant. S'il y a plusieurs éléments de contenus dans le même parent, alors ils sont frères entre eux. Enfin, lorsque les éléments sont contenus les uns dans les autres sur plusieurs niveaux, alors, on peut parler de descendants et d'ancêtres.
Ci-dessous, les deux boutons sont stylés en une seule fois avec la classe .push_button
. Ensuite, je me sers de la relation grand-parent et enfant. Je cible le bouton de connexion, mais je ne le cible pas directement. Je désigne au préalable son grand-père qui est le div
d'identificateur dialog-connexion
.
#10 Combinateur d'enfants directs. body > p {...}
Ici, c'est la relation parent et enfants qui est utilisée. On parle aussi d'enfants directs, d'où le nom du combinateur. Les paragraphes qui sont en fait des petits-enfants du body
ne seront pas sélectionnés. C'est le cas du "Paragraphe 3" puisqu'il est enfant direct d'un div
et pas du body
. Et c'est aussi le cas des "Paragraphe 4 et 5" car ils sont enfants directs de article
.
Seuls les "Paragraphe 1 et 2" sont sélectionnés.
Tester le code#11 Combinateur du frère adjacent. article + p {...}
Comment fonctionne ce combinateur ? Le sélecteur contient deux frères. C'est le deuxième frère qui est sélectionné.
Dans l'exemple ci-dessous, les deux frères contenus par le sélecteur sont l'élément article
et l'élément p
. Le sélecteur va sélectionner le premier élément p, soit le frère adjacent de l'élément article. Le terme adjacent ne suffit pas pour décrire ce que le sélecteur fait. En fait, il sélectionne un frère adjacent, mais qui est après.
Deux remarques :
- Comprenez bien, que seul le premier paragraphe va être sélectionné et pas celui qui contient "Second paragraphe" car, ce dernier, n'est pas adjacent à
article
. - Comprenez bien aussi, qu'il est le seul à être adjacent ET derrière, puisqu'il y a un paragraphe qui contient "Un paragraphe avant article" qui est adjacent, mais devant. Et qui, lui, ne sera pas sélectionné.
#12 Combinateur des frères adjacents. article ~ p {...}
Le fonctionnement est presque identique au combinateur précédent. Aussi, je ne vais pas reprendre ce que j'ai déjà dit. Pour une meilleure compréhension, je vous conseille de voir les deux combinateurs et de les comparer.
Avec ce combinateur, vous pouvez sélectionner tous les frères adjacents qui sont placés après. Ici les deux paragraphes, qui sont après l'élément article
, vont être sélectionnés (* contrairement à l'exemple précédent).
#13 Pseudo-classes de liens.
Les pseudo-classes sélectionnent un élément, lorsque cet élément, est dans un état particulier. La liste des pseudo-classes est longue, et dans ce tuto, je me limite à celles qui à mon avis sont les plus utilisées.
Ici, je sélectionne des liens, lorsqu'ils sont dans un état particulier.
Tester le codeJe vais aussi citer la pseudo-classe :focus
, qui permet de cibler, comme son nom l'indique, un élément qui a le focus. Je rappelle, qu'un élément qui a le focus, reçoit les événements clavier et souris. Autre exemple, si vous avez plusieurs fenêtres ouvertes sur votre écran, et que vous tapez sur une touche du clavier, c'est la fenêtre qui a le focus et elle seule qui va recevoir le caractère.
L'ordre, selon lequel, les pseudo-classes doivent être écrites, dans la feuille de style, est important. Il y a deux moyens mnémotechniques pour s'en souvenir :
- Le fameux
LoVe HAte
, qui rappelle cet ordre : Link, Visited, Hover, Active. - Et un autre moins connu, pas très classe 😕 mais plus précis
LoVe Fuck HAte
qui rappelle cet ordre : Link, Visited, Focus, Hover, Active.
J'ai déjà parlé de ça, dans le tutoriel sur les liens. Consultez-le si vous avez besoin d'informations complémentaires.
#14 Pseudo-classes d'input.
Vous pouvez sélectionner l'état des éléments input
, selon qu'ils sont checked
, enabled
, disabled
.
Ci-dessous :
- Le premier
input
est uncheckbox
. Il est coché par l'attributchecked='checked'
et lorsqu'il est coché, je lui mets unmargin
de100px
. Donc, quand on va le décocher, les marges vont revenir à leurs valeurs par défaut, et on va pouvoir constater la différence. - Le deuxième
input
est uninput
de typetext
. Il estenabled
, ce qui veut dire qu'il est prêt à être utilisé pour recevoir des caractères. Je le sélectionne dans cet état, avec le sélecteurinput:enabled
, et je mets la couleur de son contenu à vert. - Le troisième
input
est aussi uninput
de typetext
. Lui estdisabled
, ce qui veut dire que l'on ne peut pas modifier son contenu. Je le sélectionne dans cet état, avec le sélecteurinput:disabled
, et je mets la couleur de son contenu à rouge.
#15 Pseudo-classes nième enfant.
Vous pouvez sélectionner des éléments, en fonction de leur rang, dans leur conteneur parent. Vous pouvez sélectionner le nième enfant d'un conteneur en utilisant nth-child(n)
où n est le rang de l'élément (en commençant à 1). Vous pouvez sélectionner un premier enfant, en utilisant first-child
. Vous pouvez sélectionner un dernier enfant, en utilisant last-child
.
Par exemple ci-dessous :
- Avec le sélecteur
p:first-child
la condition pour qu'un élément soit sélectionné, c'est que ce soit un paragraphe ET un enfant de rang 1. Peu importe qui est le parent. Dans mon exemple, il n'y a que le paragraphe qui contient "Premier paragraphe" qui est premier enfant. Il est enfant d'undiv
, mais, comme je l'ai dit, peu importe. - Avec le sélecteur
p:nth-child(2)
la condition pour qu'un élément soit sélectionné, c'est que ce soit un paragraphe ET qu'il soit enfant de rand 2. C'est le cas du paragraphe qui contient "Deuxième paragraphe". - Avec le sélecteur
p:last-child
la condition pour qu'un élément soit sélectionné, c'est que ce soit un paragraphe ET qu'il soit dernier enfant. C'est le cas du paragraphe qui contient "Cinquième paragraphe".
Dans l'exemple ci-dessous, j'ai été obligé de placer un div
, car dans le code de test, je donne des explications qui sont placées derrière le paragraphe qui contient "Cinquième paragraphe". Du coup, sans le div
, ce paragraphe n'est plus en position de last-child
.
Vous pouvez sélectionner les rangs pairs(even) et les rangs impairs(odd). Dans le tutoriel sur les tableaux, j'ai utilisé odd
et even
dans plusieurs exemples.
#16 Pseudo-élément ::first-letter
Les pseudo-éléments vont sélectionner des morceaux de contenu. Il faut mettre un double ::
devant un pseudo-élément.
Ci-dessous, le pseudo-élément ::first-letter
sélectionne la première lettre du contenu de l'élément p.
#17 Pseudo-élément ::first-line
Le pseudo-élément ::first-line
sélectionne la première ligne. Ici, c'est dynamique, on voit bien que si on change la taille de la fenêtre et bien, on va changer le contenu de la première ligne. On ne pourrait pas mettre un span
, car on ne saurait pas où le mettre.
#18 Pseudo-éléments ::before et ::after
A l'aide de la propriété content
, je peux ajouter du contenu avant, ou après un élément. A noter, que les contenus insérés, seront enfants du contenu initial.
Ci-dessous, avec les sélecteurs a::before
et a::after
, je désigne un endroit. Respectivement, l'endroit qui se trouve avant les liens, et celui qui se trouve après les liens. Avec la propriété content
, je vais aller ajouter du contenu à l'endroit que j'ai désigné.
Donc ci-dessous, je vais ajouter du contenu avant, et après les liens, puisque j'ai utilisé ::before
et aussi ::after
.