Skip to content

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-child et :last-child
  • Créer du contenu généré avec ::before et ::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

SyntaxeDescriptionExemple
[attribut]Éléments ayant cet attribut (peu importe la valeur)input[required]
[attribut="valeur"]Éléments dont l'attribut a exactement cette valeurinput[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-child et :last-child ciblent 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-child cible le premier enfant d'un parent
  • :last-child cible 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 ::before et ::after permettent 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é content est obligatoire pour que ::before et ::after fonctionnent, 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

  • content est obligatoire (même vide : content: "";)
  • Par défaut, ::before et ::after sont des éléments inline
  • Utilisez display: block ou position: absolute pour 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.scss

index.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
  • ::before et ::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

  1. Voici un code HTML qui contient une section avec plusieurs articles. Attention, il y a des div imbriquées à l'intérieur des articles.
  2. Insérer ce code HTML fourni dans votre fichier index.html, à l'intérieur de la balise <body>.
  3. En SCSS, cibler uniquement les divs enfants directs de la section pour leur appliquer une bordure bleue (#0000ff) et un fond gris clair (#f0f0f0).
  4. 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

  1. Créer une div avec des titres h3 et des paragraphes alternés
  2. On veut que le paragraphe qui suit immédiatement un h3 a un style différent (police plus grande, couleur différente)
  3. Les autres paragraphes restent avec le style par défaut
  4. 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

  1. Créer un formulaire avec : nom (text), courriel (email), téléphone (tel), message (textarea), et un bouton submit
  2. Les champs text, email et tel ont une bordure bleue (#3498db)
  3. Le champ textarea a un fond légèrement gris (#f8f9fa)
  4. Le bouton submit a un fond vert (#27ae60)
  5. 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-child et :last-child pour les différencier.

Consignes

  1. Créer une liste de 5 éléments (par exemple des tâches)
  2. Le premier élément (tâche 1) a un fond jaune clair (#fff3cd) avec une icône ajoutée avec ::before et la propriété content.
    1. Par exemple: content:"✔ "
  3. Le dernier élément (tâche 5) a un fond gris clair (#e9ecef)
  4. 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 ::before et ::after pour ajouter des éléments visuels sans modifier le HTML.

Consignes

  1. 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 dans content)
  2. 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 ::before et ::after pour y arriver tout en donnant un style particulier et différents aux guillemets)
  3. 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.
    1. 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;
}