Appearance
Module 5 : Sélecteurs Avancés CSS - Cibler avec précision
Introduction
Les sélecteurs avancés CSS permettent de cibler des éléments HTML avec une grande précision, sans avoir besoin d'ajouter des classes supplémentaires à votre code HTML. Ces sélecteurs exploitent la structure du document, les attributs des éléments et leur position dans l'arborescence DOM pour appliquer des styles de manière ciblée et élégante.
Note SCSS : Dans ce module, nous utiliserons l'imbrication SCSS pour organiser nos règles de manière claire et lisible. Vos fichiers de styles seront dans
css/styles.scss.
Objectifs du cours
- Comprendre et utiliser les sélecteurs de combinaison (
>et+) - Maîtriser les sélecteurs d'attributs
[attribut] - Appliquer les pseudo-classes
:first-childet:last-child - Créer du contenu généré avec
::beforeet::after - Combiner ces sélecteurs pour des styles précis et maintenables
Théorie
1 : Le sélecteur enfant direct >
Définition
Le sélecteur enfant direct (
>) cible uniquement les éléments qui sont des enfants immédiats d'un élément parent spécifié. Contrairement au sélecteur descendant (espace), il ne sélectionne pas les éléments imbriqués plus profondément.
Mise en contexte
Ce sélecteur est utile lorsque vous avez une structure HTML imbriquée et que vous souhaitez styliser uniquement le premier niveau d'enfants, sans affecter les éléments plus profonds.
Exemple pratique
HTML :
html
<main>
<div>
<h2>Titre de la section</h2>
<p>Ceci est un paragraphe dans la div enfant direct de main </p>
<p>Un autre paragraphe avec du texte.</p>
<!-- Élément imbriqué plus profond -->
<div>
<h3>Sous-titre</h3>
<p>Paragraphe dans la sous-section, qui est une div imbriquée plus profondément</p>
</div>
</div>
</main>Dans cet exemple, nous voulons styliser uniquement les éléments <div> qui sont des enfants directs de main, sans affecter les éléments plus imbriqués comme
css
main {
border: 1px solid #ccc;
padding: 20px;
/* Cible uniquement les enfants directs (<div>) de main */
/* Les éléments plus imbriqués ne sont pas affectés */
}
main > div {
background-color: #f0f0f0;
padding: 15px;
margin-bottom: 10px;
border: 2px solid red;
}
main > div h2 {
color: #333;
font-size: 1.5em;
}
main > div p {
color: #666;
line-height: 1.6;
}CSS (styles.scss) : En SCSS, avec l'imbrication, ceci donnerait :
scss
main {
border: 1px solid #ccc;
padding: 20px;
/* Cible uniquement les enfants directs (<div>) de main */
/* Les éléments plus imbriqués ne sont pas affectés */
> div {
background-color: #f0f0f0;
padding: 15px;
margin-bottom: 10px;
border: 2px solid red;
h2 {
color: #333;
font-size: 1.5em;
}
p {
color: #666;
line-height: 1.6;
}
}
}Points importants
- Le symbole
>signifie "enfant direct de" - Très utile pour les menus à plusieurs niveaux
- Permet d'éviter les conflits de styles entre niveaux imbriqués
Exercice pratique
Compléter l'exercice 1
2 : Le sélecteur de frère adjacent +
Définition
Le sélecteur de frère adjacent (
+) cible l'élément qui suit immédiatement un autre élément, à condition qu'ils partagent le même parent. Il ne sélectionne que le premier élément frère suivant.
Mise en contexte
Ce sélecteur est parfait pour styliser un élément en fonction de son voisin immédiat. Par exemple, ajouter un espacement spécial après un titre, ou styliser un paragraphe qui suit une image.
Exemple pratique
HTML :
html
<article>
<h2>Titre de l'article</h2>
<p>Premier paragraphe après le titre.</p>
<p>Deuxième paragraphe.</p>
<p>Troisième paragraphe.</p>
</article>Nous voulons que le premier paragraphe après le titre <h2> ait un style différent (texte plus grand et en gras) pour servir d'introduction.
CSS normal :
css
article h2 {
color: #2c3e50;
margin-bottom: 10px;
}
article h2 + p {
font-size: 1.2rem;
font-weight: bold;
color: #7f8c8d;
}
article p {
line-height: 1.6;
margin-bottom: 15px;
}CSS (styles.scss) :
scss
article {
h2 {
color: #2c3e50;
margin-bottom: 10px;
}
/* Cible UNIQUEMENT le <p> qui suit immédiatement le <h2> */
h2 + p {
font-size: 1.2rem;
font-weight: bold;
color: #7f8c8d;
}
p {
line-height: 1.6;
margin-bottom: 15px;
}
}Autre exemple : espacement entre éléments
HTML :
html
<div class="boutons">
<button>Bouton 1</button>
<button>Bouton 2</button>
<button>Bouton 3</button>
</div>CSS normal :
css
.boutons button {
padding: 10px 20px;
background-color: #3498db;
color: white;
border: none;
cursor: pointer;
}
.boutons button + button {
margin-left: 10px;
}CSS (styles.scss) :
scss
.boutons {
button {
padding: 10px 20px;
background-color: #3498db;
color: white;
border: none;
cursor: pointer;
}
/* Ajoute une marge gauche à chaque bouton qui suit un autre bouton */
button + button {
margin-left: 10px;
}
}Résultat : le premier bouton n'a pas de marge gauche, mais tous les suivants en ont une.
Points importants
- Le symbole
+signifie "frère immédiat suivant" - Les deux éléments doivent avoir le même parent
- Seul le premier élément suivant est ciblé
Exercice pratique
Compléter l'exercice 2
3 : Le sélecteur d'attribut [attribut]
Définition
Le sélecteur d'attribut cible les éléments HTML qui possèdent un attribut spécifique, avec ou sans valeur particulière. Il permet de styliser des éléments en fonction de leurs attributs comme
href,type,data-*, etc.
Sélecteur par attribut : Référence
Mise en contexte
Ce sélecteur est très pratique pour styliser des liens externes différemment des liens internes, ou pour cibler des champs de formulaire selon leur type.
Syntaxes disponibles
| Syntaxe | Description | Exemple |
|---|---|---|
[attribut] | Éléments ayant cet attribut (peu importe la valeur) | input[required] |
[attribut="valeur"] | Éléments dont l'attribut a exactement cette valeur | input[type="text"] |
[attribut^="valeur"] | Valeur commence par... | a[href^="https://"] |
[attribut$="valeur"] | Valeur se termine par... | img[src$=".png"] |
[attribut*="valeur"] | Valeur contient... | a[href*="google"] |
Exemple pratique : liens externes vs internes
HTML :
html
<nav>
<a href="/accueil">Accueil</a>
<a href="/services">Services</a>
<a href="https://google.com" target="_blank">Google</a>
<a href="https://github.com" target="_blank">GitHub</a>
</nav>CSS normal :
css
nav a {
color: #3498db;
text-decoration: none;
margin-right: 15px;
}
/* Règle qui cible tous les liens avec l'attribut target="_blank" */
nav a[target="_blank"] {
color: #e74c3c;
}
/* Règle qui cible tous les liens dont l'attribut href commence par "https://" */
nav a[href^="https://"] {
font-weight: bold;
}CSS (styles.scss) :
scss
nav {
a {
color: #3498db;
text-decoration: none;
margin-right: 15px;
&[target="_blank"] {
color: #e74c3c;
}
&[href^="https://"] {
font-weight: bold;
}
}
}Exercice pratique
Compléter l'exercice 3
4 : Les pseudo-classes :first-child et :last-child
Définition
Les pseudo-classes
:first-childet:last-childciblent respectivement le premier et le dernier enfant d'un élément parent. Elles permettent de styliser ces éléments différemment sans leur ajouter de classe spéciale.
Mise en contexte
Ces pseudo-classes sont idéales pour gérer les bordures, les marges ou les styles particuliers des premiers et derniers éléments d'une liste, d'un menu ou d'un groupe d'éléments.
Exemple pratique : liste avec bordures
HTML :
html
<ul class="liste-contacts">
<li>Jean Dupont</li>
<li>Marie Tremblay</li>
<li>Pierre Martin</li>
<li>Sophie Gagnon</li>
</ul>Nous voulons une bordure entre chaque élément, mais pas au-dessus du premier ni en-dessous du dernier.
CSS normal :
css
.liste-contacts {
list-style: none;
padding: 0;
border: 1px solid #ddd;
}
.liste-contacts li {
padding: 15px;
border-bottom: 1px solid #ddd;
}
.liste-contacts li:last-child {
border-bottom: none;
}
.liste-contacts li:first-child {
font-weight: bold;
background-color: #f8f9fa;
}CSS (styles.scss) :
scss
.liste-contacts {
list-style: none;
padding: 0;
border: 1px solid #ddd;
li {
padding: 15px;
border-bottom: 1px solid #ddd;
}
/* Retire la bordure du dernier élément */
li:last-child {
border-bottom: none;
}
/* Style spécial pour le premier élément */
li:first-child {
font-weight: bold;
background-color: #f8f9fa;
}
}Exemple pratique : menu de navigation
HTML :
html
<nav class="nav-horizontal">
<a href="#">Accueil</a>
<a href="#">À propos</a>
<a href="#">Services</a>
<a href="#">Contact</a>
</nav>CSS normal :
css
.nav-horizontal {
display: flex;
background-color: #2c3e50;
}
.nav-horizontal a {
color: white;
text-decoration: none;
padding: 15px 25px;
border-right: 1px solid #34495e;
}
.nav-horizontal a:last-child {
border-right: none;
}
.nav-horizontal a:first-child {
border-radius: 5px 0 0 5px;
}
.nav-horizontal a:last-child {
border-radius: 0 5px 5px 0;
}CSS (styles.scss) :
scss
.nav-horizontal {
display: flex;
background-color: #2c3e50;
a {
color: white;
text-decoration: none;
padding: 15px 25px;
border-right: 1px solid #34495e;
}
/* Retire la bordure du dernier lien */
a:last-child {
border-right: none;
}
/* Arrondit les coins du premier lien */
a:first-child {
border-radius: 5px 0 0 5px;
}
/* Arrondit les coins du dernier lien */
a:last-child {
border-radius: 0 5px 5px 0;
}
}Points importants
:first-childcible le premier enfant d'un parent:last-childcible le dernier enfant d'un parent- Ces pseudo-classes sont dynamiques : si l'ordre des éléments change, les styles s'adaptent automatiquement
Exercice pratique
Compléter l'exercice 4
5 : Les pseudo-éléments ::before et ::after
Définition
Les pseudo-éléments
::beforeet::afterpermettent de créer du contenu généré avant ou après le contenu réel d'un élément, directement via CSS. Ce contenu n'existe pas dans le HTML mais apparaît visuellement sur la page.
Mise en contexte
Ces pseudo-éléments sont utilisés pour ajouter des icônes, des décorations, des indicateurs visuels ou des éléments graphiques sans modifier le HTML. Ils nécessitent obligatoirement la propriété content.
Important : La propriété
contentest obligatoire pour que::beforeet::afterfonctionnent, même si elle est vide (content: "";).
Exemple pratique : indicateur de lien externe
HTML :
html
<p>Visitez notre <a href="https://exemple.com" class="externe">site partenaire</a> pour plus d'infos.</p>
<p>Consultez notre <a href="/contact">page contact</a> pour nous joindre.</p>CSS normal :
css
a {
color: #3498db;
text-decoration: none;
}
.externe::after {
content: " ↗";
font-size: 0.8em;
}CSS (styles.scss) :
scss
a {
color: #3498db;
text-decoration: none;
}
.externe {
/* Ajoute une flèche après le lien externe */
&::after {
content: " ↗";
font-size: 0.8em;
}
}Résultat : Le lien externe affiche "site partenaire ↗" avec la flèche ajoutée automatiquement.
Exemple pratique : citation stylisée
HTML :
html
<blockquote class="citation">
La simplicité est la sophistication suprême.
</blockquote>CSS normal :
css
.citation {
position: relative;
padding: 20px 40px;
font-style: italic;
font-size: 1.3rem;
color: #555;
background-color: #f9f9f9;
border-left: 4px solid #3498db;
}
.citation::before {
content: "«";
font-size: 2rem;
color: #3498db;
position: absolute;
left: 10px;
top: 10px;
}
.citation::after {
content: "»";
font-size: 2rem;
color: #3498db;
}CSS (styles.scss) :
scss
.citation {
position: relative;
padding: 20px 40px;
font-style: italic;
font-size: 1.3rem;
color: #555;
background-color: #f9f9f9;
border-left: 4px solid #3498db;
/* Guillemet ouvrant avant le texte */
&::before {
content: "«";
font-size: 2rem;
color: #3498db;
position: absolute;
left: 10px;
top: 10px;
}
/* Guillemet fermant après le texte */
&::after {
content: "»";
font-size: 2rem;
color: #3498db;
}
}Exemple pratique : décoration visuelle
HTML :
html
<h2 class="titre-decore">Nos Services</h2>CSS normal :
css
.titre-decore {
text-align: center;
color: #2c3e50;
position: relative;
padding-bottom: 15px;
}
.titre-decore::after {
content: "";
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: 3px;
background-color: #3498db;
}CSS (styles.scss) :
scss
.titre-decore {
text-align: center;
color: #2c3e50;
position: relative;
padding-bottom: 15px;
/* Ligne décorative sous le titre */
&::after {
content: "";
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: 3px;
background-color: #3498db;
}
}Points importants
contentest obligatoire (même vide :content: "";)- Par défaut,
::beforeet::aftersont des élémentsinline - Utilisez
display: blockouposition: absolutepour un contrôle complet - Ils sont enfants de l'élément sur lequel ils sont appliqués
- Ils ne fonctionnent pas sur les éléments auto-fermants comme
<img>ou<input>
Exercice pratique
Compléter l'exercice 5
En résumé
Les selecteurs avancés CSS offrent une grande flexibilité pour cibler précisément les éléments HTML sans alourdir le code avec des classes supplémentaires. En combinant ces sélecteurs, vous pouvez créer des styles optimisés et maintenables sans devoir nécessairement passer des classes CSS supplémentaires dans votre HTML.
Démonstration complète
Cette section illustre une démonstration complète utilisant tous les sélecteurs avancés vus dans ce module. C'est simplement pour vous montrer une démo complète qui réunit tous les concepts vus jusqu'à présent.
Carte de profil avec sélecteurs avancés
Cette démonstration combine tous les sélecteurs vus dans ce module pour créer des cartes de profil stylisées.
Structure du projet VS Code :
RACINE/
├── index.html
└── css/
└── styles.scssindex.html
Voir le code
html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sélecteurs Avancés - Démo Module 5</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div class="container">
<h1>Sélecteurs Avancés CSS</h1>
<section class="cartes">
<article class="carte actif">
<h3>Jean Dupont</h3>
<p>Développeur Web</p>
<p>5 ans d'expérience</p>
<a href="https://linkedin.com" target="_blank">LinkedIn</a>
</article>
<article class="carte actif">
<h3>Marie Tremblay</h3>
<p>Designer UX</p>
<p>3 ans d'expérience</p>
<a href="/portfolio">Portfolio</a>
</article>
<article class="carte inactif">
<h3>Pierre Martin</h3>
<p>Chef de projet</p>
<p>8 ans d'expérience</p>
<a href="https://github.com" target="_blank">GitHub</a>
</article>
</section>
</div>
</body>
</html>styles/styles.scss
Voir le code
scss
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 40px 20px;
}
.container {
max-width: 1000px;
margin: 0 auto;
}
h1 {
text-align: center;
color: white;
margin-bottom: 40px;
}
.cartes {
display: flex;
gap: 30px;
justify-content: center;
flex-wrap: wrap;
}
.carte {
background: white;
padding: 30px;
border-radius: 15px;
width: 280px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
h3 {
color: #2c3e50;
margin-bottom: 15px;
/* ::before pour ajouter une icône avant le nom */
&::before {
content: "👤 ";
}
}
/* Sélecteur + : le premier <p> après <h3> est le titre du poste */
h3 + p {
font-weight: bold;
color: #3498db;
font-size: 1.1rem;
}
p {
margin-bottom: 10px;
color: #7f8c8d;
}
/* :last-child pour styliser le lien (dernier enfant) */
a:last-child {
display: inline-block;
margin-top: 15px;
color: #3498db;
text-decoration: none;
}
/* Sélecteur d'attribut : liens externes */
a[target="_blank"] {
&::after {
content: " ↗";
font-size: 0.8em;
}
}
}
/* Classes pour différencier les cartes actives */
.carte.actif {
border-left: 4px solid #27ae60;
}
/* Classes pour différencier les cartes inactives */
.carte.inactif {
opacity: 0.6;
border-left: 4px solid #e74c3c;
}
/* :first-child : première carte avec style spécial */
.cartes > .carte:first-child {
transform: scale(1.05);
}Conclusion
Cette démonstration illustre l'utilisation combinée de plusieurs sélecteurs avancés :
>: Ciblage de la première carte enfant direct+: Style du paragraphe suivant immédiatement le titre- Classes : Différenciation des cartes selon leur statut
[attribut]: Différenciation des liens externes:first-child: Mise en avant de la première carte::beforeet::after: Ajout d'icônes et d'indicateurs visuels
Exercice synthèse
Dans cet exercice, on vous demande de combiner plusieurs sélecteurs afin d'arriver à un résultat précis à partir d'un projet de départ. Ce type d'exercice se rapproche du genre de questions à développement demandées en examen
Exercice 6
Voir l'exercice 6 synthèse : Mise en pratique des sélecteurs avancés
Exercices pratiques
Exercice 1 : enfant direct > (Facile)
Énoncé
Créez une section d'articles où seuls les articles enfants directs de la section ont un style spécial. Utilisez le sélecteur
>pour cibler uniquement les enfants immédiats.
Consignes
- Voici un code HTML qui contient une section avec plusieurs articles. Attention, il y a des div imbriquées à l'intérieur des articles.
- Insérer ce code HTML fourni dans votre fichier
index.html, à l'intérieur de la balise<body>. - En SCSS, cibler uniquement les divs enfants directs de la section pour leur appliquer une bordure bleue (#0000ff) et un fond gris clair (#f0f0f0).
- Utiliser le sélecteur
>pour éviter d'affecter d'autres éléments potentiellement imbriqués, comme les div à l'intérieur des articles.
Structure HTML suggérée
html
<main>
<section>
<div>
<h3>Article 1</h3>
<p>Contenu de l'article 1.</p>
<div>
<img src="https://placehold.co/200x200" alt="Image placeholder">
</div>
</div>
<div>
<h3>Article 2</h3>
<p>Contenu de l'article 2.</p>
<!--div imbriquée-->
<div>
<img src="https://placehold.co/200x200" alt="Image placeholder">
</div>
</div>
</section>
</main>Exercice 2 : frère adjacent + (Facile)
Énoncé
Voici une div avec des titres et des paragraphes où le paragraphe qui suit immédiatement un titre a un style différent. Utilisez le sélecteur de frère adjacent
+pour cibler uniquement le paragraphe adjacent.
Consignes
- Créer une div avec des titres h3 et des paragraphes alternés
- On veut que le paragraphe qui suit immédiatement un h3 a un style différent (police plus grande, couleur différente)
- Les autres paragraphes restent avec le style par défaut
- Utiliser le sélecteur
+pour cibler uniquement le paragraphe adjacent aux balise h3
Soi le code HTML suivant
html
<div class="contenu">
<h3>Titre 1</h3>
<p>Paragraphe après le titre 1.</p>
<p>Autre paragraphe - Lorem ipsum dolor sit amet.</p>
<p>Autre paragraphe - Lorem ipsum dolor sit amet.</p>
<h3>Titre 2</h3>
<p>Paragraphe après le titre 2.</p>
<h3>Titre 3</h3>
<p>Paragraphe après le titre 3.</p>
</div>Exercice 3 : attributs [attribut] (Intermédiaire)
Énoncé
Créez un formulaire de contact avec des styles différents selon les attributs des champs. Utilisez les sélecteurs d'attributs pour différencier les types de champs.
Consignes
- Créer un formulaire avec : nom (text), courriel (email), téléphone (tel), message (textarea), et un bouton submit
- Les champs
text,emailettelont une bordure bleue (#3498db) - Le champ
textareaa un fond légèrement gris (#f8f9fa) - Le bouton
submita un fond vert (#27ae60) - Réalise le tout en utilisant que des sélecteurs d'attributs, aucune classe ou id dans le formulaire : que du HTML standard
Exercice 4 : :first-child et :last-child (Intermédiaire)
Énoncé
Créez une liste d'éléments où le premier et le dernier ont des styles distincts. Utilisez
:first-childet:last-childpour les différencier.
Consignes
- Créer une liste de 5 éléments (par exemple des tâches)
- Le premier élément (tâche 1) a un fond jaune clair (#fff3cd) avec une icône ajoutée avec
::beforeet la propriétécontent.- Par exemple:
content:"✔ "
- Par exemple:
- Le dernier élément (tâche 5) a un fond gris clair (#e9ecef)
- Les éléments du milieu (tâches 2, 3, 4) ont une bordure entre eux
Structure HTML suggérée
html
<ul class="liste-taches">
<li class="complete">Tâche 1</li>
<li>Tâche 2</li>
<li class="complete">Tâche 3</li>
<li>Tâche 4</li>
<li>Tâche 5</li>
</ul>Exercice 5 : ::before et ::after (Intermédiaire)
Énoncé
Créez des éléments décorés avec du contenu généré. Utilisez
::beforeet::afterpour ajouter des éléments visuels sans modifier le HTML.
Consignes
- Créer une liste de 5 tâches où certaines seront indiquées comme complétées ave ce symbole : ✔ (utiliser
::after, vous pouvez copier ce symbole directement et le coller danscontent) - En dessous, créer un paragraphe qui est une citation de votre choix. Une citation est souvent accompagnée de guillemets ouvrants et fermants (utiliser
::beforeet::afterpour y arriver tout en donnant un style particulier et différents aux guillemets) - En dessous, créer des boutons avec des icônes avant le texte (utiliser
::before). Par exemple, un bouton "Envoyer" avec une icône d'avion en papier (✈) avant le texte, mais toujours à l'intérieur du bouton.- Faites la même chose pour un bouton Télécharger avec une icône de flèche vers le bas (⬇)
Note : Tous les contenus générés utilisent la propriété content
Exercice 6 synthèse : Mise en pratique des sélecteurs avancés
Objectif
L'exercice suivant est un exercice de synthèse qui demande à utiliser tous les sélecteurs avancés vus dans ce module. Important : vous devez le réaliser sans modifier le HTML ou modifier les règles CSS existantes.
Vous devez compléter le fichier styles.scss sans modifier les règles CSS déjà présentes. Allez à la fin du fichier pour ajouter vos nouvelles règles.
Fichiers de départ à télécharger
📦 Télécharger les fichiers de départ
Dans ce projet, on vous donne également une prise écran d'un résultat attendu pour vous guider visuellement. Autrement dit, il manque des règles dans le projet de départ afin d'obtenir le rendu final. Vous ajoutez ces règles à la fin du fichier
styles.scss.
Tâches à réaliser :
1) Paragraphe principal - Sélecteur enfant direct
Consigne : Le paragraphe principal dans le main doit avoir un fond différent, un padding et une taille de police plus grande. Attention, les autres paragraphes à l'intérieur du main (plus loin) ne doivent pas être affectés.
Résultat attendu : Le paragraphe d'introduction doit avoir un fond gris clair, du padding, une taille de police légèrement plus grande et être en italique. Essayer de se rapproche de l'exemple visuelle fournie.
2) Navigation - Sélecteur enfant dernier
Consigne : Dans la navigation, utiliser un sélecteur avancé pour isoler le span qui contient les liens FR/EN.
Contraintes : Vous ne pouvez pas modifier le HTML pour ajouter une classe ou un id.
Résultat attendu : Le span contenant FR/EN doit avoir une couleur spéciale, une bordure et un fond blanc.
3) Formulaire - Sélecteur voisin (+)
Consigne : Dans le formulaire, créer des règles qui utilisent le sélecteur voisin (+) pour cibler uniquement les inputs qui suivent immédiatement un label.
Résultat attendu : Seuls les champs input et textarea qui suivent directement un label doivent avoir les styles appliqués (largeur 100%, padding, bordure, etc.).
4) Formulaire - Sélecteur par attribut
Consigne : Dans le formulaire, utiliser le sélecteur par attribut pour que les champs de type "text" et "email" aient un style différent.
Résultat attendu : Les inputs de type text et email doivent avoir un fond bleu clair et une bordure rouge.
5) Colonnes - Combinaison de sélecteurs
Consigne : Les 2 premières colonnes doivent avoir un arrière-plan gris en utilisant la combinaison des sélecteurs avancés vus dans le cours.
Résultat attendu : Les deux premières sections (colonnes) doivent avoir un fond gris, et leurs liens doivent être bleus.
6) Liens externes - Pseudo-éléments
Consigne : Les liens URL externes (ceux qui commencent par "http") doivent être en italique et soulignés, et avoir une icône spéciale qui indique visuellement qu'ils sont externes.
Résultat attendu : Tous les liens externes doivent être en italique, soulignés, et afficher une flèche (↗) après le texte.
Corriger des exercices
Ex 1 : Sélecteur enfant direct >
HTML (index.html) :
html
<main>
<section>
<div>
<h3>Article 1</h3>
<p>Contenu de l'article 1.</p>
<div>
<img src="https://placehold.co/200x200" alt="Image placeholder">
</div>
</div>
<div>
<h3>Article 2</h3>
<p>Contenu de l'article 2.</p>
<!--div imbriquée-->
<div>
<img src="https://placehold.co/200x200" alt="Image placeholder">
</div>
</div>
</section>
</main>SCSS (css/styles.scss) :
scss
main {
section {
/* Cible uniquement les divs enfants directs de section */
> div {
border: 1px solid #0000ff;
background-color: #f0f0f0;
padding: 10px;
margin-bottom: 10px;
}
}
}Ex 2 : Sélecteur de frère adjacent +
HTML (index.html) :
html
<div class="contenu">
<h3>Titre 1</h3>
<p>Paragraphe après le titre 1.</p>
<p>Autre paragraphe.</p>
<h3>Titre 2</h3>
<p>Paragraphe après le titre 2.</p>
</div>SCSS (css/styles.scss) :
scss
.contenu {
h3 {
color: #2c3e50;
margin-bottom: 5px;
}
/* Cible uniquement le paragraphe qui suit immédiatement un h3 */
h3 + p {
font-size: 1.2rem;
font-weight: bold;
color: #7f8c8d;
}
p {
line-height: 1.6;
margin-bottom: 15px;
}
}Ex 3 : attributs [attribut]
HTML (index.html) :
html
<form action="#" method="post">
<label for="nom">Nom :</label>
<input type="text" id="nom" name="nom" required>
<label for="courriel">Courriel :</label>
<input type="email" id="courriel" name="courriel" required>
<label for="telephone">Téléphone :</label>
<input type="tel" id="telephone" name="telephone">
<label for="message">Message :</label>
<textarea id="message" name="message" rows="5"></textarea>
<button type="submit">Envoyer</button>
</form>
<p>Visitez <a href="https://example.com">ce site</a> pour plus d'infos.</p>SCSS (css/styles.scss) :
scss
form {
/* Champs text, email, tel */
input[type="text"],
input[type="email"],
input[type="tel"] {
border: 2px solid #3498db;
padding: 8px;
margin-bottom: 10px;
width: 100%;
}
/* Textarea */
textarea {
background-color: #f8f9fa;
border: 1px solid #ccc;
padding: 8px;
margin-bottom: 10px;
width: 100%;
}
/* Bouton submit */
button[type="submit"] {
background-color: #27ae60;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
}
}
/* Liens externes commençant par https:// */
a[href^="https://"]::after {
content: " →";
color: #3498db;
}Ex 4 : :first-child et :last-child
HTML (index.html) :
html
<ul class="liste-taches">
<li class="complete">Tâche 1</li>
<li>Tâche 2</li>
<li class="complete">Tâche 3</li>
<li>Tâche 4</li>
<li>Tâche 5</li>
</ul>SCSS (css/styles.scss) :
scss
.liste-taches {
list-style: none;
padding: 0;
li {
padding: 10px;
border-bottom: 1px solid #ddd;
}
/* Premier élément */
li:first-child {
background-color: #fff3cd;
}
li:first-child::before {
content: "✓ ";
color: green;
}
/* Dernier élément */
li:last-child {
background-color: #e9ecef;
border-bottom: none;
}
}Ex 5 : ::before et ::after
HTML (index.html) :
html
<ul class="liste-taches">
<li class="complete">Tâche 1</li>
<li>Tâche 2</li>
<li class="complete">Tâche 3</li>
<li>Tâche 4</li>
<li>Tâche 5</li>
</ul>
<p class="citation">La simplicité est la sophistication suprême.</p>
<button class="btn-envoyer">Envoyer</button>
<button class="btn-telecharger">Télécharger</button>SCSS (css/styles.scss) :
scss
/* Liste de tâches avec symbole de completion */
.liste-taches {
list-style: none;
padding: 0;
li {
padding: 10px;
margin-bottom: 5px;
border-left: 4px solid #ddd;
}
.complete::after {
content: " ✔";
color: #27ae60;
font-weight: bold;
}
}
/* Citation avec guillemets ouvrants et fermants */
.citation {
position: relative;
font-style: italic;
padding: 20px 40px;
background-color: #f8f9fa;
border-left: 4px solid #3498db;
&::before {
content: "«";
font-size: 2rem;
color: #3498db;
position: absolute;
left: 10px;
top: 10px;
}
&::after {
content: "»";
font-size: 2rem;
color: #3498db;
position: absolute;
right: 10px;
bottom: -10px;
}
}
/* Boutons avec icônes */
.btn-envoyer,
.btn-telecharger {
background-color: #3498db;
color: white;
border: none;
padding: 10px 20px;
margin-right: 10px;
cursor: pointer;
}
.btn-envoyer::before {
content: "✈ ";
}
.btn-telecharger::before {
content: "↓ ";
}Ex 6 (synthèse)
Exemple de code SCSS pouvant arrivé au résultat attendu, en utilisant les sélecteurs avancés vus dans ce module :
scss
/* ============================================
STYLES À CODER SELON LES CONSIGNES DE L'EXERCICE
============================================ */
/* Le paragraphe principal dans le main doit avoir un fond différent, un padding et une taille de police plus grande */
/* Attention, les autres paragraphes à l'intérieur du main (plus loin) ne doivent pas être affectés */
main > p {
font-size: 1.1rem;
line-height: 1.7;
margin-bottom: 40px;
padding: 20px;
background-color: #f8f9fa;
font-style: italic;
}
/* Dans la navigation, utiliser un des sélecteurs avancés isoler le div qui contient FR/EN
Vous ne pouvez pas modifier le HTML pour ajouter une classe ou un id
*/
nav span:last-child {
color: $primary-color;
font-weight: bold;
border: 1px solid white;
padding: 5px;
background-color: white;
a{
color: $secondary-color;
&:hover {
text-decoration: underline;
}
}
}
/* Dans le formulaire, créer une ou des règles qui utilisent le sélecteur voisin (+) pour cibler QUE les inputs dans le formulaire */
form label + input,
form label + textarea {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 16px;
}
/* Dans le formulaire, utiliser le sélecteur par attribut pour que les champs text et email aient un fond différent et une bordure rouge*/
form input[type="text"],
form input[type="email"] {
background-color: #f0f8ff;
border: 1px solid red;
}
/* Les 2 premières colonnes ont un arrière-plan gris. Il faut y arriver avec la combinaison des sélecteurs avancés vus dans le cours */
section:first-child,
section:first-child + section {
background-color: rgb(214, 214, 214);
a{
color: rgb(0, 0, 255);
}
}
/* Les liens url externes (ceux qui commencent par http) doivent être en italique et soulignés
ET avoir un icone spécial qui indique visuellement qu'ils sont externes */
a[href^="http"] {
font-style: italic;
text-decoration: underline;
}
a[target=_blank]::after {
content: " ↗";
color: $primary-color;
}Vérification des connaissances
Question 1
Quelle est la différence entre le sélecteur descendant normal avec espace (.class1 div) et le sélecteur enfant direct (.class1 > div) ?
Réponse
Le sélecteur descendant (espace) cible tous les descendants à n'importe quel niveau d'imbrication, tandis que le sélecteur enfant direct (>) cible uniquement les enfants immédiats (premier niveau).
scss
/* Tous les <li> descendants, peu importe le niveau */
.menu li {
color: blue;
}
/* Uniquement les <li> enfants directs de .menu */
.menu > li {
color: blue;
}Question 2
Comment cibler un paragraphe qui suit immédiatement un titre <h2> ?
Réponse
Utilisez le sélecteur de frère adjacent (+) qui cible l'élément suivant immédiat partageant le même parent.
scss
h2 + p {
font-size: 1.2rem;
font-weight: bold;
}Question 3
Comment styliser tous les liens qui s'ouvrent dans un nouvel onglet (ayant target="_blank") ?
Réponse
Utilisez le sélecteur d'attribut avec la syntaxe [attribut="valeur"] pour cibler les éléments ayant cette valeur exacte.
scss
a[target="_blank"] {
color: #e74c3c;
}Question 4
Quelle propriété est obligatoire pour que ::before et ::after fonctionnent et affiche quelque chose après ou avant l'élément ?
Réponse
La propriété content est obligatoire, même si elle est vide. Sans cette propriété, le pseudo-élément ne sera pas affiché.
scss
.element {
&::before {
content: ""; /* Obligatoire, même vide */
display: block;
width: 20px;
height: 20px;
background-color: blue;
}
}Question 5
Comment retirer la bordure du dernier élément d'une liste ?
Réponse
Utilisez la pseudo-classe :last-child pour cibler le dernier enfant et lui retirer la bordure.
scss
ul {
li {
border-bottom: 1px solid #ddd;
}
li:last-child {
border-bottom: none;
}
}Question 6
Comment ajouter une flèche (↗) après tous les liens externes sans modifier le HTML ?
Réponse
Combinez le sélecteur d'attribut avec le pseudo-élément ::after pour ajouter du contenu généré.
scss
a[href^="https://"] {
&::after {
content: " ↗";
font-size: 0.8em;
}
}Question 7
Comment cibler tous les champs de formulaire dont le type commence par "pass" (comme "password") ?
Réponse
Utilisez le sélecteur d'attribut avec ^= qui signifie "commence par".
scss
input[type^="pass"] {
border: 2px solid #e74c3c;
background-color: #ffeaea;
}Question 8
Quel sélecteur permet de cibler le premier élément d'une liste <ul> ?
Réponse
Utilisez la pseudo-classe :first-child pour cibler le premier enfant d'un élément parent.
scss
ul li:first-child {
font-weight: bold;
color: #2c3e50;
}Question 9
Soit l'extrait de code suivant :
html
<main>
<div class="bg-light"> div1 </div>
<div> div2 </div>
<div class="bg-light"> div3 </div>
<div> div4 </div>
<div class="bg-light"> div5 </div>
<div> div6 </div>
<div class="bg-light"> div7 </div>
<div> div8 </div>
<div class="bg-light"> div9 </div>
</main>css
.bg-light {
background-color: #f0f0f0;
}Question : écrivez une règle CSS qui permettrait de cibler les div 2,4,6 et 8 pour leur appliquer un arrière-plan foncé (#ccc) sans ajouter de classe supplémentaire dans le HTML ?
Réponse
Utilisez le sélecteur de frère adjacent (+) pour cibler les div qui suivent immédiatement une div avec la classe bg-light.
css
.bg-light + div {
background-color: #ccc;
}