Cibler des éléments selon leur position dans l'arbre DOM grâce aux combinateurs.
>, ~, +) pour cibler un élément en fonction de sa relation avec un autre élément dans l'arbre DOM.
Les sélecteurs simples ciblent des éléments directement. Les sélecteurs combinés, eux, exploitent la hiérarchie parent-enfant-frère du DOM pour des ciblages plus précis.
Les 4 combinateurs essentiels :
| Combinateur | Nom | Syntaxe | Signification |
|---|---|---|---|
(espace) |
Descendant | A B |
B est un descendant de A (à n'importe quelle profondeur) |
> |
Enfant direct | A > B |
B est un enfant direct de A (niveau immédiat) |
~ |
Frère général | A ~ B |
B est un frère suivant de A (même parent, après A) |
+ |
Frère adjacent | A + B |
B est le frère directement suivant de A (juste après) |
A B cible tous les éléments B qui sont des descendants de A, quelle que soit la profondeur. Il peut y avoir des éléments intermédiaires entre A et B.
/* Cible TOUS les <p> à l'intérieur d'un <article>,
même s'ils sont dans des div intermédiaires */
article p {
line-height: 1.8;
}
/* Cible tous les <a> dans la navigation */
nav a {
color: white;
text-decoration: none;
}
Le sélecteur descendant cible les <p> à toutes les profondeurs dans <article>
>)A > B cible uniquement les éléments B qui sont des enfants directs de A — c'est-à-dire au niveau hiérarchique immédiat. Aucun élément intermédiaire n'est admis.
/* Cible uniquement les <p> enfants directs d'un <article> */
article > p {
margin-bottom: 1rem;
}
/* Cible uniquement les <li> enfants directs d'un <ul> */
ul > li {
padding: 0.5rem 0;
}
Le sélecteur enfant direct > ne cible que le premier niveau
~)A ~ B cible tous les éléments B qui sont des frères suivants de A — c'est-à-dire placés après A au même niveau hiérarchique, avec le même parent. Les frères précédents ne sont pas ciblés.
/* Cible tous les <p> qui suivent un <h2> au même niveau */
h2 ~ p {
padding-left: 1rem;
border-left: 3px solid #e2e8f0;
}
Le sélecteur h2 ~ p cible tous les <p> après le <h2>
+)A + B cible uniquement le premier élément B qui suit directement A — le frère immédiat. Si un autre élément est entre A et B, B n'est pas ciblé.
/* Cible uniquement le premier <p> juste après un <h2> */
h2 + p {
font-size: 1.1rem;
font-weight: 600;
color: #2563eb;
}
/* Cible l'input juste après un label */
label + input {
margin-top: 0.5rem;
}
Le sélecteur h2 + p cible uniquement le <p> juste après le <h2>
Comparaison en direct
/* Sélecteur descendant : espace */
article p {
background: #dbeafe; /* Bleu clair */
border-left: 3px solid #2563eb;
}
/* Sélecteur enfant direct : > */
article > p {
background: #fee2e2; /* Rouge clair */
border-left: 3px solid #dc2626;
}
<p> enfant direct → Rouge (enfant direct ✓)
<p> dans un <div> → Bleu (descendant ✓, enfant direct ✗)
<p> enfant direct → Rouge (enfant direct ✓)
Comparaison en direct
/* Frère adjacent : + (un seul élément) */
h2 + p {
color: #2563eb;
font-weight: 700;
}
/* Frère général : ~ (tous les éléments suivants) */
h2 ~ p {
color: #64748b;
padding-left: 1rem;
}
<p> adjacent → Bleu gras (+ ciblé ✓, ~ ciblé ✓)
<p> dans un <div> → Gris (pas au même niveau)
<p> frère général → Gris (~ ciblé ✓, + NON ciblé ✗)
<p> autre frère → Gris (~ ciblé ✓, + NON ciblé ✗)
Navigation hiérarchique
/* Le sélecteur descendant cible tous les liens dans la nav */
nav a {
display: inline-block;
padding: 0.5rem 1rem;
color: white;
text-decoration: none;
border-radius: 6px;
}
nav a:hover {
background: rgba(255,255,255,0.2);
}
/* L'enfant direct cible uniquement les liens de premier niveau */
nav > ul > li > a {
font-weight: 700;
text-transform: uppercase;
}
Premier paragraphe après un titre
/* Le premier paragraphe après un h2 est une "chape" */
h2 + p {
font-size: 1.1rem;
color: #475569;
font-weight: 500;
border-left: 4px solid #2563eb;
padding-left: 1rem;
}
/* Tous les paragraphes suivants */
h2 ~ p {
line-height: 1.8;
margin-bottom: 1rem;
}
Labels et inputs alignés
/* Cible les labels enfants directs du formulaire */
form > label {
display: block;
font-weight: 600;
margin-bottom: 0.25rem;
margin-top: 1rem;
}
/* Cible les inputs juste après les labels */
label + input {
width: 100%;
padding: 0.6rem;
border: 2px solid #e2e8f0;
border-radius: 6px;
font-size: 1rem;
}
/* Cible les inputs focus */
label + input:focus {
border-color: #2563eb;
outline: none;
box-shadow: 0 0 0 3px rgba(37,99,235,0.15);
}
Griser les tâches après une tâche terminée
/* Quand une tâche est marquée "terminée",
toutes les tâches suivantes sont grisées */
.tache-terminee ~ .tache {
opacity: 0.5;
text-decoration: line-through;
}
/* FAUX — tu voulais cibler les <p> enfants directs */
div p { ... } /* Ceci cible AUSSI les <p> imbriqués ! */
/* CORRECT — utiliser > pour les enfants directs uniquement */
div > p { ... }
/* Ceci ne cible que le PREMIER <p> après <h2> */
h2 + p { ... }
/* Ceci cible TOUS les <p> après <h2> */
h2 ~ p { ... }
/* Enfant direct : pas d'espace */
h2 > p { ... }
/* Descendant : avec un espace */
h2 p { ... }
/* Attention ! Un espace parasite change tout ! */
/* FAUX — trop spécifique et fragile */
div > section > article > div > p > span { ... }
/* CORRECT — utiliser une classe à la place */
.article-highlight { ... }
> à l'espace quand tu veux cibler uniquement les enfants directs — c'est plus explicite et performant..nav > .nav-item est préférable à nav > li.~ et + pour les effets contextuels (style conditionnel)./* ✅ Bonne pratique : ciblage précis avec classe */
.sidebar > .menu-item {
padding: 0.75rem;
}
/* ✅ Bonne pratique : effet conditionnel */
.section-title + .section-content {
margin-top: 0;
}
/* ✅ Bonne pratique : navigation profonde */
.breadcrumb > .breadcrumb-item + .breadcrumb-item::before {
content: " / ";
margin: 0 0.5rem;
color: #94a3b8;
}
Exercice 1 : Descendant vs Enfant direct
Écris deux règles CSS pour un élément <ul> contenant des <li> avec parfois des <ul> imbriquées :
ul li : padding de 0.5rem (descendant)ul > li : border-left de 3px solid blue (enfant direct)Solution :
ul li {
padding: 0.5rem;
}
ul > li {
border-left: 3px solid blue;
}
Exercice 2 : Frère adjacent
Écris un sélecteur pour cibler uniquement le <p> qui suit directement un <h1> et lui appliquer :
font-size: 1.2remcolor: #475569font-style: italicSolution :
h1 + p {
font-size: 1.2rem;
color: #475569;
font-style: italic;
}
Exercice 3 : Combinaison complète
Écris un sélecteur pour cibler tous les liens <a> qui sont dans une liste <ul> qui est un enfant direct d'un <nav>. Le style :
text-decoration: nonecolor: #2563ebfont-weight: 600Solution :
nav > ul a {
text-decoration: none;
color: #2563eb;
font-weight: 600;
}
Projet : Page d'article avec navigation
Crée une page HTML avec :
<nav> contenant un <ul> avec des liens<article> avec des <h2> et des <p><aside> avec des informations supplémentairesCSS requis (utilise les combinateurs) :
nav a : style de lien (descendant)nav > ul : flexbox pour aligner les items (enfant direct)h2 + p : style spécial pour le premier paragraphe (frère adjacent)h2 ~ p : style pour les paragraphes suivants (frère général)article > p:first-of-type : premier paragraphe de l'articleQuiz rapide
+ et ~ ?div > p cible un <p> à 3 niveaux de profondeur ? Oui / Nonh1 + p cible tous les <p> après le <h1> ? Oui / NonA B> : A > B+ cible le frère immédiat suivant ; ~ cible tous les frères suivants> ne cible que les enfants directs (niveau 1)+ ne cible que le premier <p> directement adjacent au <h1>