• 4 hours
  • Easy

Free online content available in this course.

You can get support and mentoring from a private teacher via videoconference on this course.

Got it!

Last updated on 1/8/18

Ciblons nos éléments

Log in or subscribe for free to enjoy all this course has to offer!

Une des choses essentielles en CSS, c'est bien la sélection des éléments ! Savoir appliquer un style à tous nos paragraphes, à nos titres, aux éléments ayant telle ou telle classe ou encore aux enfants de la balise ayant tel id... Tout ceci fait partie du quotidien de n'importe quel Web Designer.

CSS3 nous propose beaucoup de nouvelles façons de sélectionner nos éléments ; peut-être même en utilisez-vous déjà sans savoir qu'ils ne sont spécifiés que depuis le troisième niveau de CSS ! Quoi qu'il en soit, vous risquez bien vite d'y être accrocs. :)

Sélectionner selon l'attribut

Vous ne le savez peut-être pas, mais depuis CSS2 il est possible de sélectionner nos éléments selon leurs attributs. Ainsi, il est tout à fait correct de faire ceci :

/* Tous les paragraphes avec un id
spécifié seront écrits en rouge */
p[id]
{
    color: red;
}

/* Les zones de saisies
auront un fond bleu */
input[type="text"]
{
    background-color: blue;
}

/* Les images dont l'info-bulle est une liste de valeurs
séparées par des espaces et dont l'une d'elle est "jolie"
auront une bordure rouge */
img[title~="jolie"]
{
    border: 1px solid red;
}

/* Les vidéos dont l'attribut "data-config" est une liste
de valeurs séparées par des tirets et dont la première valeur
est "big" */
video[data-config|="big"]
{
    border: 1px solid red;
}

Sachez qu'il est également possible de faire un méga-mix en combinant plusieurs sélecteurs sur un seul élément !

/* Les zones de saisies ayant la classe "commentaire"
et un id de spécifié, et dont le texte d'indication est une liste de
valeurs séparées par des espaces et dont l'une
d'elles est "ici" auront un fond bleu */
input.commentaire[id][type="text"][placeholder~="ici"]
{
    background-color: blue;
}

Ouf ! :p

CSS3 nous propose d'aller plus loin avec une syntaxe qui n'est pas sans rappeler les expressions régulières... En bien moins compliqué, rassurez-vous !

Nous pouvons désormais sélectionner nos éléments selon le début, la fin ou le milieu des valeurs de leurs attributs. Ça reste flou dans votre esprit ? Un exemple s'impose. :)

Imaginons par exemple que nous ayons ce genre de page HTML :

<!DOCTYPE html>
<html>
    <head>
        <title>Votre avatar</title>
	<meta charset="UTF-8" />
    </head>
    <body>
        <ul>
	    <li id="stats_titre">Statistiques</li>
	    <li id="total_stats_niveau">Niveau 5</li>
	    <li id="total_stats_pv">10 Points de Vie</li>
	    <li id="total_stats_pf">0 Point de Magie</li>
	    <li id="inventaire_titre">Inventaire</li>
	    <li id="total_inventaire_arc">3 Arcs</li>
	    <li id="total_inventaire_fleche">0 Flèches</li>
	    <li id="total_inventaire_bouclier">1 Bouclier</li>
	</ul>
    </body>
</html>

CSS3 nous permet de styliser tous les éléments de notre liste dont l'id commence par total, finit par titre ou encore contient le mot inventaire.

Pour ce faire, la syntaxe à utiliser est la suivante :

  • E[attr^="A"] : sélectionne les éléments E dont l'attribut attrcommence par A.

  • E[attr$="A"] : sélectionne les éléments E dont l'attribut attrfinit par A.

  • E[attr*="A"] : sélectionne les éléments E dont l'attribut attrcontientA.

Ainsi, pour en revenir à notre exemple, nous pouvons styliser notre liste de la sorte :

/* La liste globale, rien de nouveau pour l'instant */
ul
{
    width: 300px;
    margin: auto;
    border: 2px solid #000;
    padding: 0px;
    list-style: none;
}

/* Les objets de la liste, toujours rien de nouveau ! */			
li
{
    padding-left: 5px;
}

/* Les éléments de la liste dont l'id FINIT par "titre" */	
li[id$="titre"]
{
    padding: 3px;
    padding-left: 30px;
    background-color: #af5151;
    color: #fff;
    font-weight: bold;
}


/* Les éléments de la liste dont l'id COMMENCE par "total" */		
li[id^=total]
{
    background-color: #e5cfcf;
}


/* Les éléments de la liste dont l'id CONTIENT "stats" */			
li[id*=stats]
{
    font-size: 20px;
}

/* Les éléments de la liste dont l'id CONTIENT "inventaire" */			
li[id*=inventaire]
{
    text-align: center;
    font-size: 15px;
    padding-left: 0px;
}

Essayer !

Bien entendu, il est possible de filtrer sur n'importe quel attribut, pas seulement l'id.

Cette nouvelle technique est donc très pratique, mais attention à ne pas la surexploiter : l'utilisation des classes est parfois plus adaptée à la situation. ;)

Sélectionner selon la position

Il peut nous arriver de vouloir styliser nos éléments selon leur position dans le DOM : n'avez-vous jamais essayé de mettre en gras tous vos paragraphes sauf le premier de la page ? Ou, plus probablement, de colorer alternativement les lignes d'un tableau ?

Différents moyens nous sont alors offerts, que ce soit du 100% CSS en utilisant des classes ou en jonglant avec JavaScript.

CSS3 nous facilite la vie en nous permettant de sélectionner les éléments directement selon leur position ! Concrètement, cela se traduit par l'utilisation de pseudo-formats, et ces derniers vont devenir vos meilleurs amis. :D

L'élément racine

Nous allons passer très rapidement sur ce sélecteur car, comme vous allez vous en rendre compte, il ne nous sera pas super utile.

CSS3 introduit en effet le pseudo-format :root. Il permet de sélectionner l'élément correspondant seulement s'il est la racine de notre document. Petit rappel au cas où : la racine est le tout premier élément d'un document, celui qui englobe tous les autres.
En clair et concis, :root sélectionne notre balise <html>. :p

Pourquoi s'en servir alors ? On peut sélectionner cette balise en écrivant html, tout simplement !

Peut-être pensez-vous, à tort, que le CSS ne s'applique que sur des documents (x)HTML. Eh bien non ! Ce merveilleux langage peut styliser n'importe quel type de documents XML !

Un XML peut contenir n'importe quel type de balise : sa racine peut être n'importe quoi, pas forcément <html> ! Le pseudo-format :root sera donc bien plus utile pour les XML. :)

Sélectionner le nième élément

Sélectionner les premiers éléments enfants.

Imaginons que nous ayons réalisé un jeu Web et que nous souhaitons afficher le top 5 des meilleurs joueurs. Nous pourrions ainsi avoir un fichier de ce style :

<!DOCTYPE html>
<html>
    <head>
	<title>Top 5</title>
	<meta charset="UTF-8" />
    </head>
    <body>
	<table>
            <thead>
		<tr>
	            <th colspan="2">TOP 5 DES JOUEURS !</th>
		</tr>
	    </thead>
	    <tbody>
	        <tr>
		    <td>1</td>
		    <td>Alex Térieur</td>
		</tr>
		<tr>
		    <td>2</td>
		    <td>Mona Bruti</td>
		</tr>
		<tr>
		    <td>3</td>
		    <td>Théo Bligé</td>
		</tr>
		<tr>
		    <td>4</td>
		    <td>Jean Bon</td>
		</tr>
		<tr>
		    <td>5</td>
		    <td>Justine Goutte</td>
		</tr>
	    </tbody>
        </table>
    </body>
</html>

Pour commencer, stylisons-le de façon très basique avec le code CSS ci-dessous. Il n'y a rien de nouveau pour le moment, vous ne devriez avoir aucun mal à le comprendre. :)

/* C'est l'occasion pour vous montrer :root ! */
:root
{
    background-color: #e3e3e3;
}
		
/* Notre tableau en lui-même */
table
{
    width: 500px;
    margin: auto;
    border-top: 0px;
    border-collapse: collapse;
    font-size: 16px;
}

/* Son en-tête */
thead
{
    background-color: #8f5bff;
    border-left: 2px solid #8f5bff;
    border-right: 2px solid #8f5bff;
    border-top: 2px solid #621df7;
    color: #f3f3f3;
}
		
/* Son corps */
tbody
{
    background-color: #f3f3f3;
    border: 2px solid #8f5bff;
}

Ceci produira le (relativement) joli tableau qui suit :

Image utilisateur

Nous voulons maintenant mettre en évidence les trois meilleurs du top 5 : nous pouvons par exemple augmenter la taille d'écriture de leur nom.
Pour cela, nous n'utiliserons aucune classe mais plutôt le pseudo-format :nth-child(n), où n est la position de notre élément à sélectionner.

/* La première ligne du corps de notre tableau */
tbody tr:nth-child(1)
{
    font-size: 24px;
    font-weight: bold;
}
		
/* Puis sa seconde ligne */
tbody tr:nth-child(2)
{
    font-size: 20px;
    font-weight: bold;
}
		
/* Et enfin sa troisième */
tbody tr:nth-child(3)
{
    font-size: 18px;
    font-weight: bold;
}

Essayer !

Sélectionner les derniers éléments enfants.

:nth-child(n) permet de sélectionner le nième élément enfant en partant du début. Mais comment faire pour les sélectionner à partir de la fin ? Tout simplement avec :nth-last-child(n) !

Celui-ci fonctionne exactement de la même façon que son frère, passons donc directement à l'exemple en ajoutant ceci à notre code. :)

/* La dernière ligne du corps de notre tableau */
tbody tr:nth-last-child(1)
{
    font-size: 10px;
    font-style: italic;
}
		
/* Puis l'avant-dernière ligne */
tbody tr:nth-last-child(2)
{
    font-size: 14px;
    font-style: italic;
}

Essayer !

Filtrer selon le type de l'élément

Une chose que devez comprendre est que les pseudos-formats que nous venons de voir doivent se lire ainsi :

Styliser l'élément correspondant uniquement s'il est le nième enfant de son élément parent.

Vous ne voyez pas ou je veux en venir ? Prenons par exemple ce document :

<!DOCTYPE html>
<html>
    <head>
	<title>Un petit test...</title>
	<meta charset="UTF-8" />
    </head>
    <body>
	<p>Coucou, je suis le premier paragraphe !</p>
	<p>Et je suis le second paragraphe !</p>
	<ul>
            <li>Et moi,</li>
	    <li>je suis</li>
	    <li>une liste !</li>
	</ul>
	<p>Et je suis un troisième paragraphe, dingue !</p>
	<p>Je suis un quatrième paragraphe !</p>
    </body>
</html>

Admettons que nous souhaitons styliser uniquement le troisième paragraphe. Nous pensons donc à écrire ceci :

p:nth-child(3)
{
    background-color: #f3f3f3;
}

Essayer !

Mais ceci ne fonctionne pas ! o_O
Pourquoi ?

Parce que notre troisième paragraphe n'est pas le troisième enfant de son parent (qui est la balise <body>), il est placé en quatrième position !

Bien sûr, il est possible de tricher et d'utiliser :nth-child(4), voire :nth-last-child(2) (notre troisième paragraphe est bien l'avant-dernier enfant !), mais CSS3 nous propose une autre solution pour résoudre ce petit soucis.

Cette solution prend la forme du pseudo-format :nth-of-type(n) : celui-ci agit de la même façon que son cousin :nth-child(n), excepté qu'il prend en compte le type des éléments !

/* Sélectionne le troisième paragraphe */
p:nth-of-type(3)
{
    background-color: #f3f3f3;
}

Essayer !

La différence entre :nth-child(n) et :nth-of-type(n) est assez subtile, n'hésitez pas à faire plusieurs tests pour bien la comprendre. :)

Toujours plus fort, toujours plus loin !

Tous les pseudo-formats que nous venons de voir sont très puissants, mais ils ne nous ont pas encore tout révélé !

Jusque-là, nous les avons utilisés avant des valeurs numériques : :nth-child(2), :nth-of-type(3) etc...
Et bien sachez qu'il est possible de spécifier une formule mathématique à la place d'un simple nombre !

Pour ceux à qui les maths donnent des boutons, rassurez-vous : cette formule est très simple puisqu'elle est sous la forme : $xn+a$

n est une constante utilisée par le navigateur, x un multiplicateur et a un indice de décalage.
Et si vous ne vous rappelez pas de ça, ce n'est pas grave. :p

Souvenez-vous juste que nous devons renseigner les valeurs de x et de a !

Il est donc possible d'écrire ce genre de chose :

p:nth-of-type(2n+1)
{
    background-color: #f3f3f3;
}

Essayer !

Alors, que se passe-t-il ici ?
Tout d'abord, le navigateur prend la valeur de a, qui est ici 1, et stylise l'élément correspondant : notre premier paragraphe a donc fond de couleur claire.

Ensuite, le navigateur prend la valeur de x, ici 2 : il comprend ainsi qu'il doit styliser le deuxième paragraphe qui suit celui qu'il vient de styliser, puis encore le deuxième, et encore le deuxième, et ainsi de suite.

Un autre exemple ?

p:nth-of-type(3n+2)
{
    background-color: #f3f3f3;
}

a vaut ici 2 : le navigateur va donc commencer par styliser le second paragraphe.
x vaut 3, il prendra donc le troisième paragraphe suivant pour le styliser, et encore le troisième, etc.

Essayez de visualiser le résultat dans votre tête avant d'essayer ce code. ;)

Essayer !

Utiliser ce type de formule est très pratique pour styliser un tableau ! Si nous voulons colorer une ligne sur deux, il nous suffit d'écrire ceci :

/* Lignes paires */
table tr:nth-child(2n)
{
    background-color: #f3f3f3;
}

/* Lignes impaires */
table tr:nth-child(2n+1)
{
    background-color: #e3e3e3;
}

Le sélecteur de négation

Rien de tel qu'un petit exemple pour vous montrer à quel point le prochain sélecteur que nous verrons s'avère pratique.

Mettons-nous en situation : nous avons un formulaire et nous souhaitons mettre une bordure rouge de trois pixels autour de tous les <input>, excepté ceux destinés à accueillir un mot de passe qui doivent avoir une bordure normale. Voici donc comment nous pourrions procéder :

input
{
   border: 3px solid red;
}

input[type="password"]
{
   border: default;
}

Essayer !

Et ça ne fonctionne pas ! Entre nous, je m'y attendais un peu. :-°

Pourquoi ? Parce que la propriété border n'accepte pas la valeur default ! Ni même la valeur auto.
Alors comment faire ?

Avec le sélecteur :not() !

Tout comme :nth-child(), ce sélecteur prend un paramètre à indiquer entre ses parenthèses. Ce paramètre peut être n'importe quel sélecteur CSS !

:not() agira alors comme un filtre en retirant de la sélection attachée tous les éléments correspondants à la sélection passée en paramètre.

Traduisons en français l'exemple suivant pour que tout soit clair :

p.small:not(.red)
Sélectionne tous les paragraphes ayant la classe small, exceptés ceux ayant la classe red.

Notre problème se résout donc de la façon la plus simple qui soit !

/* Tous les inputs, sauf ceux des mots de passe */
input:not([type="password"])
{
   border: 3px solid red;
}

Essayer !

Pour information, sachez qu'il est possible de combiner les :not(). Si nous voulons appliquer une bordure sur tous les <input> sauf ceux des mots de passe et des URL, nous pouvons donc écrire ceci :

/* Tous les inputs, sauf ceux des mots de passe et des URL */
input:not([type="password"]):not([type="url"])
{
   border: 3px solid red;
}

Autres sélecteurs plus marginaux

Pour terminer ce chapitre en douceur, voici trois autres sélecteurs dont vous vous servirez probablement moins, mais il est toujours utile de les connaître. :)

:checked

Comme vous l'avez sûrement deviné, ce pseudo-format s'applique sur les <input> de type checkbox ou radio.

Il permet de les sélectionner uniquement si elles sont cochées.

Bon, sur le papier c'est alléchant, mais en pratique ça l'est un peu moins : les navigateurs ne nous permettent pas de styliser les cases à cocher comme on le souhaite !
On peut cependant se servir de cette fonctionnalité pour modifier le style des éléments situés près d'une case à cocher :

/* Les labels situés juste après une case à cocher */
input[type="checkbox"] + label
{
    color: red;
}
			
/* Les labels situés juste après une case cochée */
input[type="checkbox"]:checked + label
{
    color: green;
}

Essayer !

Et tout ça sans JavaScript. :)

:empty

Le pseudo-format :empty sélectionne un élément n'ayant aucun enfant : aucune autre balise, aucun texte, rien du tout ! Il faut que notre élément soit complètement vide.

/* Les paragraphes vides */
p:empty
{
    height: 20px;
    width: 100px;
    background-color: #c00;
    border: 2px solid #f00;
}

Essayer !

Malheureusement, :empty ne peut pas être utilisé pour sélectionner les zones de formulaires vides... Mais je suis sûr que vous lui trouverez une utilité. :)

:target

Le dernier mais pas le moindre, :target nous permet de sélectionner les éléments qui sont ciblés. Pour qu'un élément soit considéré comme ciblé, il doit posséder un id dont la valeur est égale à celle de l'ancre de la page.

Souvenez-vous de vos cours HTML sur les ancres :

<!-- Ce code provient du cours de M@teo21 -->
<h1>Ma grande page</h1>

<p>
   Aller directement à la partie traitant de :<br />
   <a href="#cuisine">La cuisine</a><br />
   <a href="#rollers">Les rollers</a><br />
   <a href="#arc">Le tir à l'arc</a><br />
</p>

Ici, selon le lien cliqué, l'élément dont l'id est cuisine sera ciblé, ou celui dont l'id est rollers ou encore celui dont l'id est arc.

Dans son exemple, M@teo21 a utilisé des titres comme cibles de ces liens. Il est donc possible de les sélectionner via CSS3 de cette façon :

/* On applique un fond beige pâle sur les titres ciblés */
h2:target
{
    background-color: #fdfae2;
}

Essayer !

Comme vous le voyez, :target peut nous être très pratique selon les situations. Ce sélecteur nous permet des choses qui nous étaient impossibles à réaliser avant sans l'aide de JavaScript : nous pouvons par exemple penser à un système de texte secret !

<h1><ins>Question :</ins> quel sélecteur cet exemple illustre-t-il ?</h1>
<fieldset>
    <legend>
        <a href="#secret">Voir la réponse</a>
        <a href="#">Cacher la réponse</a>
    </legend>
    <p id="secret">
        Le sélecteur <b>:target</b> : il est possible grâce
        à lui de faire ce type d'interface sans aucune ligne de JavaScript !
    </p>
</fieldset>
/* On cache les paragraphes */
p{display: none;}

/* Et on affiche ceux qui sont ciblés */			
p:target
{
    display: block;
}

Essayer !

Des interactions avec le visiteur en utilisant uniquement du CSS : n'est-ce pas merveilleux ? :D

CSS3 apporte donc son lot de nouveaux sélecteurs. Très puissants, ils se révèlent très pratiques et permettent de styliser nos pages de manière bien plus efficace qu'avant.

Les plus délicats à comprendre sont sans doute ceux de la famille de :nth-child(n) mais, une fois maîtrisés, on se sent tout-puissant. :soleil:

Example of certificate of achievement
Example of certificate of achievement