HTML & CSS — Cours Complet Version ultra-détaillée avec schémas, MathML et exercices corrigés

Par OpenClassrooms — Formation approfondie au développement web


 


Partie 1 : Les fondamentaux du HTML et CSS

1. Distinguer HTML et CSS — Explications approfondies

1.1. Qu'est-ce que le HTML ?

Le HTML (HyperText Markup Language) est le langage de structure d'une page web. Il a été créé par Tim Berners-Lee en 1991. Sa première version officielle (HTML 2.0) date de 1995. Aujourd'hui, nous utilisons HTML5, la dernière version majeure, qui a introduit les balises sémantiques, le support de la vidéo et de l'audio natifs, et bien d'autres fonctionnalités.

Analogies pour comprendre le rôle du HTML :
  • Architecture : HTML = les fondations, les murs porteurs, l'ossature d'une maison. Sans HTML, le contenu n'existe pas.
  • Biologie : HTML = le squelette d'un corps humain. Il donne la structure et maintient tout en place.
  • Théâtre : HTML = le texte du scénario. Il dit "ceci est un dialogue", "ceci est une didascalie".

Ce que le HTML fait concrètement :

  • Il définit les titres (<h1> à <h6>) pour structurer la hiérarchie du contenu.
  • Il crée des paragraphes (<p>) pour organiser le texte.
  • Il insère des images (<img>), des vidéos (<video>) et des audios (<audio>).
  • Il crée des liens hypertextes (<a>) pour naviguer entre les pages.
  • Il structure le contenu en listes (<ul>, <ol>), tableaux (<table>) et formulaires (<form>).
+------------------------------------------+ | STRUCTURE HTML | | | | ┌──────────────────────────────┐ | | │ <html> │ | | │ ┌────────────────────────┐ │ | | │ │ <head> │ │ | | │ │ <title>Titre</title>│ │ | | │ └────────────────────────┘ │ | | │ ┌────────────────────────┐ │ | | │ │ <body> │ │ | | │ │ <h1>Titre principal</h1>│ | | │ │ <p>Paragraphe...</p> │ │ | | │ └────────────────────────┘ │ | | └──────────────────────────────┘ | +------------------------------------------+

1.2. Qu'est-ce que le CSS ?

Le CSS (Cascading Style Sheets) est le langage de présentation d'une page web. Il a été créé en 1996 par Håkon Wium Lie et Bert Bos. Le terme "cascading" (en cascade) fait référence à la manière dont les styles se superposent et se transmettent d'un parent à ses enfants dans l'arbre DOM.

 Analogies pour comprendre le rôle du CSS :
  • Architecture : CSS = la peinture, la décoration intérieure, l'aménagement de la maison.
  • Biologie : CSS = la peau, les vêtements, la coiffure qui donnent l'apparence extérieure.
  • Théâtre : CSS = la mise en scène, les costumes, les lumières qui créent l'ambiance.

Ce que le CSS fait concrètement :

  • Il définit les couleurs de fond, de texte et de bordures.
  • Il contrôle la typographie : polices, tailles, graisses, espacements.
  • Il gère la mise en page : marges, paddings, positions, alignements.
  • Il crée des effets visuels : ombres, dégradés, animations, transitions.
  • Il assure l'adaptabilité (responsive design) : la page s'affiche correctement sur tous les écrans.

1.3. Résumé comparatif

Critère HTML CSS
Rôle Structure, contenu, sémantique Style, présentation, mise en page
Question "Qu'est-ce que c'est ?" (nature du contenu) "À quoi ça ressemble ?" (apparence du contenu)
Extension de fichier .html ou .htm .css
Syntaxe Balises <nom> avec attributs Règles sélecteur { propriété: valeur; }
Historique Tim Berners-Lee (1991) Håkon Wium Lie (1996)
Dernière version HTML5 (2014) CSS3 (modules depuis 1999)
⚠️ Erreur fréquente à éviter : Ne confondez jamais les rôles. On ne peut pas "styliser" avec du HTML (à part l'attribut style qui est une exception à éviter). Le HTML est pour la structure, le CSS pour le style. Gardez-les toujours séparés pour un code propre et maintenable.

2. Reconnaître les éléments HTML courants et leurs attributs

2.1. La structure minimale d'une page HTML

Toute page HTML valide doit commencer par une déclaration de type de document (!DOCTYPE) qui indique au navigateur qu'il s'agit de HTML5. Ensuite, la balise racine <html> contient deux sections principales :

  • <head> : Les métadonnées (non visibles) — titre, encodage, liens vers CSS, etc.
  • <body> : Le contenu visible par l'utilisateur.
<!DOCTYPE html>
<html lang="fr">
<head>
    <!-- Encodage des caractères (UTF-8 recommandé) -->
    <meta charset="UTF-8">

    <!-- Rendu responsive sur mobiles -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- Titre affiché dans l'onglet du navigateur -->
    <title>Ma première page</title>

    <!-- Lien vers la feuille de style CSS externe -->
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <!-- Tout le contenu visible va ici -->
    <h1>Bienvenue sur mon site</h1>
    <p>Ceci est mon premier paragraphe.</p>
</body>
</html>

2.2. Les éléments HTML les plus utilisés

Balise Utilité Exemple Attributs courants
<h1> à <h6> Titres hiérarchiques (h1 = plus important) <h1>Titre principal</h1> class, id, style
<p> Paragraphe de texte <p>Ceci est un paragraphe.</p> class, id
<a> Lien hypertexte (ancre) <a href="https://exemple.com">Cliquez</a> href, target, rel
<img> Image (auto-fermante) <img src="photo.jpg" alt="Description"> src, alt, width, height
<ul> / <ol> Liste non-ordonnée / ordonnée <ul><li>Item</li></ul> class, id
<div> Conteneur générique (bloc) <div class="conteneur">...</div> class, id
<span> Conteneur générique (en ligne) <span class="surligne">texte</span> class, id
<br> Saut de ligne (auto-fermant) Ligne 1<br>Ligne 2 Aucun
<hr> Ligne de séparation horizontale <hr> Aucun
<strong> Texte fortement important (gras) <strong>Important</strong> class
<em> Texte mis en emphase (italique) <em>Emphase</em> class

2.3. Les attributs HTML en détail

Les attributs sont des informations supplémentaires que l'on ajoute aux balises pour modifier leur comportement ou leur donner des métadonnées. Ils s'écrivent toujours sous la forme nom="valeur".

Attribut Utilisé sur Utilité Exemple
href <a> Définit la destination du lien (URL) <a href="https://google.com">
src <img>, <script>, <iframe> Définit la source (chemin) du fichier <img src="images/logo.png">
alt <img> Texte alternatif (accessibilité, si l'image ne charge pas) <img src="logo.png" alt="Logo de l'entreprise">
class Toutes les balises Identifie un groupe d'éléments (pour CSS/JS) <div class="carte article">
id Toutes les balises Identifie un élément unique (DOIT être unique) <h1 id="titre-principal">
target <a>, <form> Ouvrir le lien dans un nouvel onglet (_blank) <a href="#" target="_blank">
title Presque toutes Texte informatif affiché au survol (tooltip) <abbr title="HyperText Markup Language">HTML</abbr>
style Presque toutes CSS en ligne (à éviter, sauf exceptions) <p style="color: red;">Texte rouge</p>
data-* Presque toutes Données personnalisées pour JavaScript <div data-user-id="123">
role Presque toutes Rôle ARIA pour l'accessibilité <nav role="navigation">
💡 Bonne pratique : Utilisez toujours l'attribut alt sur les images. C'est obligatoire pour l'accessibilité (lecteurs d'écran pour malvoyants) et cela aide également le référencement (SEO). De plus, si l'image ne charge pas, le texte alternatif s'affiche à la place.

3. Expliquer comment les balises sémantiques structurent une page web

3.1. Qu'est-ce que la sémantique en HTML ?

Avant HTML5, les développeurs utilisaient principalement des <div> avec des classes comme class="header", class="nav", etc. Cela fonctionnait, mais cela ne donnait aucune information sémantique au navigateur, aux moteurs de recherche ou aux lecteurs d'écran.

HTML5 a introduit des balises sémantiques qui décrivent ce qu'est le contenu, et non seulement comment il est affiché. C'est un changement fondamental qui améliore :

  • L'accessibilité : Les lecteurs d'écran peuvent naviguer plus facilement.
  • Le SEO : Google comprend mieux la structure de la page.
  • La maintenabilité : Le code est plus lisible et compréhensible.

3.2. Les balises sémantiques HTML5

Balise Signification Utilisation typique Équivalent "div" avant HTML5
<header> En-tête Logo, titre principal, navigation principale <div class="header">
<nav> Navigation Menu principal, liens de navigation <div class="nav">
<main> Contenu principal Contenu central unique de la page <div class="main">
<section> Section thématique Regroupe un thème cohérent (ex: "Nos produits") <div class="section">
<article> Article Contenu indépendant et réutilisable (blog, news) <div class="article">
<aside> À côté / contenu secondaire Barre latérale, publicités, informations complémentaires <div class="sidebar">
<footer> Pied de page Mentions légales, copyright, contact, liens utiles <div class="footer">
<figure> Figure / illustration Image avec légende (<figcaption>) <div class="figure">
<figcaption> Légende d'une figure Texte descriptif d'une image ou d'un graphique <p class="caption">
<mark> Texte surligné Mettre en évidence une partie du texte <span class="highlight">
<time> Date / Heure Indiquer une date ou une heure (machine-readable) <span class="date">

3.3. Structure d'une page sémantique complète

+---------------------------------------------------+ | <body> | | ┌─────────────────────────────────────────────┐ | | │ <header> │ | | │ ┌──────────────┐ ┌────────────────────┐ │ | | │ │ <h1>Logo</h1>│ │ <nav> │ │ | | │ │ │ │ Accueil | Blog │ │ | | │ └──────────────┘ └────────────────────┘ │ | | └─────────────────────────────────────────────┘ | | ┌─────────────────────────────────────────────┐ | | │ <main> │ | | │ ┌───────────────────────────────────────┐ │ | | │ │ <section> │ │ | | │ │ ┌─────────────────────────────────┐ │ │ | | │ │ │ <article> │ │ │ | | │ │ │ <h2>Titre article</h2> │ │ │ | | │ │ │ <p>Contenu...</p> │ │ │ | | │ │ └─────────────────────────────────┘ │ │ | | │ │ ┌─────────────────────────────────┐ │ │ | | │ │ │ <article> │ │ │ | | │ │ │ <h2>Titre article 2</h2> │ │ │ | | │ │ │ <p>Contenu...</p> │ │ │ | | │ │ └─────────────────────────────────┘ │ │ | | │ └───────────────────────────────────────┘ │ | | │ ┌───────────────────────────────────────┐ │ | | │ │ <aside> (barre latérale) │ │ | | │ │ Publicité, liens connexes... │ │ | | │ └───────────────────────────────────────┘ │ | | └─────────────────────────────────────────────┘ | | ┌─────────────────────────────────────────────┐ | | │ <footer> │ | | │ © 2026 - Mentions légales │ | | └─────────────────────────────────────────────┘ | +---------------------------------------------------+
<body>
    <header>
        <h1>Mon Site Web</h1>
        <nav>
            <ul>
                <li><a href="#">Accueil</a></li>
                <li><a href="#">Blog</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
        </nav>
    </header>

    <main>
        <section>
            <h2>Nos derniers articles</h2>

            <article>
                <h3>Comment débuter en HTML</h3>
                <time datetime="2026-08-08">8 août 2026</time>
                <p>Le HTML est le langage de base du web...</p>
                <a href="#">Lire la suite</a>
            </article>

            <article>
                <h3>Les bases du CSS</h3>
                <time datetime="2026-08-07">7 août 2026</time>
                <p>Le CSS permet de styliser vos pages...</p>
                <a href="#">Lire la suite</a>
            </article>
        </section>

        <aside>
            <h4>À propos</h4>
            <p>Je suis un développeur web passionné.</p>
        </aside>
    </main>

    <footer>
        <p>&copy; 2026 MonSite - Tous droits réservés.</p>
    </footer>
</body>
✅ Pourquoi utiliser les balises sémantiques ?
  • Accessibilité : Les lecteurs d'écran (comme NVDA ou VoiceOver) peuvent identifier les zones de la page et proposer une navigation par points de repère.
  • SEO : Google et les autres moteurs de recherche accordent plus d'importance au contenu dans <main> et <article>.
  • Maintenance : Un collègue (ou vous-même dans 6 mois) comprendra immédiatement la structure de la page.
  • Validation : Le validateur W3C encourage l'utilisation de balises sémantiques.

4. Distinguer les éléments en bloc des éléments en ligne

4.1. Les éléments en bloc (block elements)

Les éléments de type bloc sont les "briques" structurelles d'une page. Ils créent des rectangles qui s'empilent verticalement.

Caractéristiques :

  • Ils prennent toute la largeur disponible de leur conteneur parent.
  • Ils provoquent un retour à la ligne (saut de ligne) avant et après eux.
  • On peut leur donner une largeur (width) et une hauteur (height).
  • Ils peuvent contenir d'autres blocs ou des éléments en ligne.

Exemples d'éléments en bloc :

<div> <p> <h1> à <h6> <ul> / <ol> <header> <section> <footer> <article> <nav> <aside> <main> <figure>
+------------------------------------------+ | <div> (bloc) | | ┌────────────────────────────────────┐ | | │ <p> (bloc) │ | | │ Texte du paragraphe │ | | └────────────────────────────────────┘ | | ┌────────────────────────────────────┐ | | │ <h2> (bloc) │ | | │ Titre de section │ | | └────────────────────────────────────┘ | | ┌────────────────────────────────────┐ | | │ <ul> (bloc) │ | | │ • Item 1 │ | | │ • Item 2 │ | | └────────────────────────────────────┘ | +------------------------------------------+

4.2. Les éléments en ligne (inline elements)

Les éléments en ligne sont utilisés pour styliser ou marquer une partie du texte à l'intérieur d'un paragraphe ou d'un bloc. Ils ne créent pas de rupture dans le flux du texte.

Caractéristiques :

  • Ils prennent uniquement la largeur de leur contenu (pas plus).
  • Ils ne provoquent pas de retour à la ligne ; ils s'enchaînent sur la même ligne.
  • On ne peut pas leur donner de width ou de height (ils s'adaptent au contenu).
  • On peut leur appliquer un padding et un margin horizontal, mais pas vertical (dans certaines conditions).

Exemples d'éléments en ligne :

<a> <span> <img> <strong> <em> <br> <time> <mark>
+------------------------------------------+ | <p> (bloc) | | Un paragraphe avec des éléments | | <span>en ligne</span>, | | un <a href="#">lien</a> | | et <strong>du texte important</strong>.| | Tous sont sur la MÊME LIGNE. | +------------------------------------------+

4.3. Le cas particulier : display: inline-block

Le CSS offre une troisième option : display: inline-block. C'est un hybride qui combine les avantages des deux :

  • L'élément s'affiche en ligne (pas de retour à la ligne).
  • On peut lui donner width, height, padding et margin (comme un bloc).
.bouton {
    display: inline-block;
    width: 150px;
    height: 50px;
    padding: 10px;
    text-align: center;
    background: #4361ee;
    color: white;
    border-radius: 8px;
}
Bouton 1
Bouton 2
Bouton 3

4.4. Résumé comparatif

Propriété Bloc (block) En ligne (inline) Bloc en ligne (inline-block)
Largeur 100% du parent Contenu uniquement Contenu ou définie
Retour à la ligne Oui (avant et après) Non Non
Peut avoir width Oui Non Oui
Peut avoir height Oui Non Oui
Peut contenir des blocs Oui Non Non
Exemples typiques div, p, h1, section span, a, img, strong Boutons, images avec texte
⚠️ Erreur fréquente : Beaucoup de débutants tentent d'appliquer width et height à un <span> ou à un <a> sans résultat. Pour qu'un élément en ligne accepte des dimensions, il faut le passer en display: inline-block ou display: block.

5. Utiliser des balises et attributs pour identifier les informations clés

5.1. Les attributs universels class et id

Ces deux attributs sont essentiels pour lier le HTML au CSS et au JavaScript. Ils permettent de cibler des éléments spécifiques.

Attribut Objectif Règles
class Identifier un groupe d'éléments - Peut être utilisé plusieurs fois
- Un élément peut avoir plusieurs classes (class="carte article important")
- Les classes sont séparées par des espaces
id Identifier un élément unique - DOIT être unique dans la page
- Un élément ne peut avoir qu'un seul ID
- L'ID doit commencer par une lettre (pas de chiffre)
<!-- ID unique -->
<h1 id="titre-principal">Accueil</h1>

<!-- Classe réutilisable -->
<p class="intro">Introduction 1</p>
<p class="intro">Introduction 2</p>

<!-- Plusieurs classes -->
<div class="carte produit populaire">
    <h3>Produit A</h3>
</div>

<!-- Un élément avec un ID ET des classes -->
<div id="article-1" class="article premium">
    <h2>Article 1</h2>
</div>

5.2. Les attributs ARIA pour l'accessibilité

ARIA (Accessible Rich Internet Applications) est un ensemble d'attributs qui améliorent l'accessibilité pour les personnes utilisant des technologies d'assistance.

Attribut ARIA Utilisation Exemple
role Définit le rôle d'un élément <nav role="navigation">
aria-label Étiquette accessible (quand pas de texte visible) <button aria-label="Fermer le menu">X</button>
aria-describedby Référence un élément qui décrit le contenu <input aria-describedby="email-help">
aria-hidden Cache un élément aux lecteurs d'écran <div aria-hidden="true">Décoration</div>
aria-expanded Indique si un élément est déplié/replié <button aria-expanded="false">Menu</button>

5.3. Les microdonnées Schema.org

Schema.org est un vocabulaire structuré (développé par Google, Microsoft, Yahoo et Yandex) qui permet d'enrichir le HTML pour que les moteurs de recherche comprennent mieux le contenu.

<!-- Exemple d'un produit avec Schema.org -->
<div itemscope itemtype="http://schema.org/Product">
    <img itemprop="image" src="casque.jpg" alt="Casque audio">
    <h2 itemprop="name">Casque sans fil Pro</h2>
    <p itemprop="description">Casque audio haute fidélité avec réduction de bruit.</p>
    <div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
        <span itemprop="price" content="99.99">99,99 €</span>
        <span itemprop="availability" content="InStock">En stock</span>
    </div>
    <div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
        <span itemprop="ratingValue">4.5</span> / 5
        <span itemprop="reviewCount">127</span> avis
    </div>
</div>
 Astuce SEO : L'utilisation de Schema.org peut améliorer l'affichage de votre site dans les résultats de recherche (rich snippets) avec des étoiles, des prix, des dates, etc. Cela augmente le taux de clics.

6. Identifier et utiliser la syntaxe CSS correcte

6.1. La syntaxe de base

Une règle CSS est composée de trois parties :

+------------------------------------------+ | | | selecteur { | | propriete: valeur; | | propriete: valeur; | | } | | | | Exemple : | | p { | | color: blue; | | font-size: 16px; | | } | | | +------------------------------------------+
  • Sélecteur : Cible l'élément (ou les éléments) à styliser.
  • Propriété : L'aspect visuel à modifier (color, font-size, etc.).
  • Valeur : La valeur appliquée à la propriété.
  • Déclaration : Une ligne propriété: valeur;
  • Règle : L'ensemble sélecteur { déclarations }

6.2. Les sélecteurs CSS

Type Syntaxe Exemple Cible
Élément balise p { color: red; } Tous les <p>
Classe .nom .intro { font-weight: bold; } Tous les éléments avec class="intro"
ID #nom #titre { font-size: 40px; } L'élément avec id="titre"
Universel * * { margin: 0; } Tous les éléments
Descendant parent enfant article p { color: gray; } Les <p> dans un <article>
Enfant direct parent > enfant ul > li { color: blue; } Les <li> enfants directs d'un <ul>
Adjacent élément1 + élément2 h1 + p { margin-top: 0; } Le <p> juste après un <h1>
Pseudo-classe :pseudo a:hover { color: red; } Lien au survol
Pseudo-élément ::pseudo p::first-letter { font-size: 2em; } Première lettre d'un paragraphe
Attribut [attr] input[type="text"] { border: 1px solid blue; } Champs de texte

6.3. Où écrire le CSS ?

  1. Feuille de style externe (✅ RECOMMANDÉ)

    Fichier séparé .css lié via <link> dans le <head>.

    <link rel="stylesheet" href="styles/main.css">
    ✅ Avantages : Réutilisable, cache navigateur, séparation claire HTML/CSS, maintenance facilitée.
  2. Style interne (⚠️ À utiliser avec modération)

    Balise <style> dans le <head>.

    <style>
        p { color: blue; }
    </style>
    ⚠️ Inconvénients : Non réutilisable, alourdit le HTML, pas de cache.
  3. Style en ligne (❌ À ÉVITER sauf exceptions)

    Attribut style sur une balise.

    <p style="color: blue; font-size: 20px;">Texte</p>
    ❌ Inconvénients : Priorité maximale (difficile à surcharger), mélange HTML/CSS, non maintenable, répétitif.
✅ Règle d'or : Toujours privilégier les feuilles de style externes. C'est la méthode professionnelle et elle respecte la séparation des préoccupations (SoC — Separation of Concerns).

7. Appliquer le CSS aux éléments HTML

7.1. Exemple complet : Carte de visite avec styles

Voici un exemple complet qui met en œuvre toutes les notions vues précédemment : structure HTML sémantique, classes, ID, et styles CSS externes.

<!-- HTML -->
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ma carte de visite</title>
    <link rel="stylesheet" href="carte.css">
</head>
<body>
    <div class="carte">
        <img src="avatar.jpg" alt="Photo de Jean Dupont" class="avatar">
        <h1 id="nom">Jean Dupont</h1>
        <p class="titre">Développeur Web Full-Stack</p>
        <p class="description">
            Passionné par les technologies web, je crée des sites modernes,
            accessibles et performants.
        </p>
        <ul class="competences">
            <li>HTML5 & CSS3</li>
            <li>JavaScript / React</li>
            <li>Node.js / Express</li>
        </ul>
        <a href="mailto:jean@exemple.com" class="bouton">Me contacter</a>
    </div>
</body>
</html>
/* CSS — carte.css */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
}

.carte {
    background: white;
    border-radius: 20px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.15);
    padding: 40px 35px 35px;
    text-align: center;
    max-width: 380px;
    width: 100%;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.carte:hover {
    transform: translateY(-6px);
    box-shadow: 0 30px 80px rgba(0,0,0,0.2);
}

.avatar {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    object-fit: cover;
    border: 4px solid #4361ee;
    margin-bottom: 18px;
}

#nom {
    font-size: 26px;
    color: #1a1a2e;
    margin-bottom: 4px;
}

.titre {
    color: #4361ee;
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 12px;
    letter-spacing: 0.5px;
}

.description {
    color: #4a4e69;
    font-size: 14px;
    line-height: 1.6;
    margin-bottom: 18px;
}

.competences {
    list-style: none;
    padding: 0;
    display: flex;
    justify-content: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 22px;
}

.competences li {
    background: #eef2ff;
    color: #2d2b4e;
    padding: 6px 16px;
    border-radius: 50px;
    font-size: 13px;
    font-weight: 500;
}

.bouton {
    display: inline-block;
    padding: 12px 35px;
    background: #4361ee;
    color: white;
    text-decoration: none;
    border-radius: 50px;
    font-weight: 600;
    transition: background 0.3s ease, transform 0.2s ease;
}

.bouton:hover {
    background: #3a0ca3;
    transform: scale(1.04);
}

.bouton:active {
    transform: scale(0.96);
}

📐 Calcul de l'ombre de la carte (box-shadow) :

ombre = ( dx , dy , r , ( r g b a ) )

où dx = décalage horizontal, dy = décalage vertical, r = rayon de flou, (rgba) = couleur avec transparence.


Partie 2 : Maîtrise de la mise en page

8. Comprendre le modèle de boîte (Box Model)

8.1. Qu'est-ce que le Box Model ?

En CSS, tous les éléments HTML sont des boîtes rectangulaires. Le Box Model est le concept qui définit comment ces boîtes sont dimensionnées et comment l'espace est calculé autour d'elles.

+-------------------------------------------------------+ | MARGIN (externe) | | ┌───────────────────────────────────────────────┐ | | │ BORDER (bordure) │ | | │ ┌───────────────────────────────────────┐ │ | | │ │ PADDING (interne) │ │ | | │ │ ┌───────────────────────────────┐ │ │ | | │ │ │ CONTENT (contenu) │ │ │ | | │ │ │ "Texte ou image" │ │ │ | | │ │ └───────────────────────────────┘ │ │ | | │ └───────────────────────────────────────┘ │ | | └───────────────────────────────────────────────┘ | +-------------------------------------------------------+

8.2. Les propriétés du Box Model

Propriété Description Exemple Valeurs typiques
content Le contenu interne (texte, image, etc.) width: 200px; px, %, em, rem, auto
padding Espace intérieur entre le contenu et la bordure padding: 20px; padding: 10px 20px; (haut/bas, gauche/droite)
border La bordure qui entoure le padding border: 2px solid #333; solid, dashed, dotted, double
margin Espace extérieur entre la boîte et les autres éléments margin: 10px; auto (centrage horizontal)

8.3. Les raccourcis (shorthands)

Pour padding et margin, il existe des syntaxes raccourcies :

/* Tous les côtés */
padding: 20px;

/* Haut + Bas | Gauche + Droite */
padding: 10px 20px;

/* Haut | Gauche + Droite | Bas */
padding: 10px 20px 30px;

/* Haut | Droite | Bas | Gauche (sens horaire) */
padding: 10px 15px 20px 25px;

/* Version explicite (équivalent) */
padding-top: 10px;
padding-right: 15px;
padding-bottom: 20px;
padding-left: 25px;

8.4. La propriété box-sizing — un concept fondamental

Par défaut (box-sizing: content-box), la largeur totale d'une boîte est :

Largeur _ totale = width + padding _ gauche + padding _ droite + border _ gauche + border _ droite

Cela signifie qu'une boîte de width: 200px avec padding: 20px et border: 2px aura une largeur réelle de 244px ! C'est souvent source d'erreurs.

La solution : utiliser box-sizing: border-box, qui inclut le padding et la bordure dans la largeur définie.

Largeur _ totale = width ( inclut _ padding + border )
/* Règle universelle — À mettre en premier dans votre CSS */
* {
    box-sizing: border-box;
}
✅ Pourquoi border-box est recommandé ?
  • Plus intuitif : si vous définissez width: 200px, la boîte fait 200px, quel que soit le padding.
  • Facilite la conception responsive : les calculs sont plus simples.
  • Adopté par la majorité des frameworks CSS (Bootstrap, Tailwind, etc.).

9. Utiliser Flexbox pour des mises en page flexibles

9.1. Qu'est-ce que Flexbox ?

Flexbox (CSS Flexible Box Layout) est un module CSS qui a révolutionné la mise en page. Avant Flexbox, on utilisait des float, display: table ou position avec des calculs complexes. Flexbox simplifie tout cela.

Il permet de répartir l'espace et d'aligner les éléments dans un conteneur sur un seul axe (horizontal ou vertical).

Deux axes en Flexbox :

+---------------------------------------------------+ | Axe principal (défini par flex-direction) | | ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←← | | | | ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ | | │ Élmt │ │ Élmt │ │ Élmt │ │ Élmt │ | | │ 1 │ │ 2 │ │ 3 │ │ 4 │ | | └─────┘ └─────┘ └─────┘ └─────┘ | | ↑ | | Axe secondaire (cross axis) | +---------------------------------------------------+

9.2. Activation de Flexbox

.conteneur-flex {
    display: flex;  /* Active le mode Flexbox */
}

9.3. Propriétés du conteneur Flex

Propriété Valeurs courantes Effet
flex-direction row (défaut), column, row-reverse, column-reverse Définit l'axe principal (direction des éléments)
justify-content flex-start, flex-end, center, space-between, space-around, space-evenly Aligne les éléments sur l'axe principal
align-items stretch (défaut), flex-start, flex-end, center, baseline Aligne les éléments sur l'axe secondaire
flex-wrap nowrap (défaut), wrap, wrap-reverse Permet le retour à la ligne lorsque les éléments ne rentrent pas
gap 10px, 1em, 5% Espace entre les éléments (équivalent à row-gap et column-gap)
align-content stretch, center, space-between Aligne les lignes sur l'axe secondaire (quand flex-wrap: wrap)

🎯 Visualisation des différentes valeurs de justify-content :

flex-start → éléments à gauche
center → éléments au centre
flex-end → éléments à droite
space-between → espace égal entre les éléments
space-around → espace égal autour des éléments
space-evenly → espace parfaitement égal

9.4. Propriétés des éléments Flex

Propriété Valeurs Effet
flex-grow Nombre (0 par défaut) Capacité d'un élément à grandir pour occuper l'espace disponible
flex-shrink Nombre (1 par défaut) Capacité d'un élément à rétrécir si l'espace manque
flex-basis auto, 200px, 50% Taille de base de l'élément avant distribution de l'espace
flex 1 (équivaut à 1 1 0) Raccourci pour flex-grow flex-shrink flex-basis
align-self auto, center, flex-start, flex-end Override align-items pour un élément spécifique
order Nombre (0 par défaut) Modifie l'ordre d'affichage (ordre numérique)

9.5. Exemple complet : Menu de navigation avancé avec Flexbox

<nav class="navbar">
    <div class="logo">🚀 MonSite</div>

    <ul class="menu">
        <li><a href="#">Accueil</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">À propos</a></li>
        <li><a href="#">Contact</a></li>
    </ul>

    <div class="auth">
        <a href="#" class="btn-connexion">Se connecter</a>
        <a href="#" class="btn-inscription">S'inscrire</a>
    </div>
</nav>
.navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: #1a1a2e;
    padding: 16px 40px;
    color: white;
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}

.logo {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.5px;
}

.menu {
    display: flex;
    list-style: none;
    gap: 30px;
}

.menu a {
    color: rgba(255,255,255,0.8);
    text-decoration: none;
    font-weight: 500;
    padding: 6px 0;
    border-bottom: 2px solid transparent;
    transition: color 0.3s, border-color 0.3s;
}

.menu a:hover {
    color: white;
    border-bottom-color: #4361ee;
}

.auth {
    display: flex;
    gap: 12px;
}

.btn-connexion {
    color: white;
    text-decoration: none;
    padding: 8px 20px;
    border: 1px solid rgba(255,255,255,0.3);
    border-radius: 50px;
    transition: background 0.3s;
}

.btn-connexion:hover {
    background: rgba(255,255,255,0.1);
}

.btn-inscription {
    color: white;
    text-decoration: none;
    padding: 8px 20px;
    background: #4361ee;
    border-radius: 50px;
    transition: background 0.3s, transform 0.2s;
}

.btn-inscription:hover {
    background: #3a0ca3;
    transform: scale(1.04);
}
💡 Astuce Flexbox : Utilisez gap plutôt que margin pour espacer les éléments Flex. C'est plus propre et cela évite les problèmes de marges qui s'accumulent.

10. Utiliser CSS Grid pour des mises en page en 2 dimensions

10.1. Qu'est-ce que CSS Grid ?

CSS Grid est un système de mise en page bidimensionnel. Contrairement à Flexbox (1D), Grid permet de contrôler à la fois les lignes et les colonnes simultanément. C'est idéal pour les mises en page complexes comme les tableaux de bord, les galeries, ou les interfaces d'administration.

+-----------------------------------------------+ | Grille 3 colonnes × 3 lignes | | ┌─────┬─────┬─────┐ | | │ 1,1 │ 1,2 │ 1,3 │ | | ├─────┼─────┼─────┤ | | │ 2,1 │ 2,2 │ 2,3 │ | | ├─────┼─────┼─────┤ | | │ 3,1 │ 3,2 │ 3,3 │ | | └─────┴─────┴─────┘ | | | | Un élément peut occuper plusieurs cellules | | ┌─────────┬─────┬─────┐ | | │ 1,1 │ 1,2 │ 1,3 │ | | │ (sur 2 ├─────┼─────┤ | | │ colonnes)│ 2,2 │ 2,3 │ | | ├─────────┴─────┴─────┤ | | │ 3,1 │ 3,2 │ 3,3 │ | | └─────────────────────┘ | +-----------------------------------------------+

10.2. Activation de Grid

.conteneur-grid {
    display: grid;
}

10.3. Propriétés du conteneur Grid

Propriété Valeurs courantes Effet
grid-template-columns 200px 1fr 200px, repeat(3, 1fr) Définit les colonnes et leur taille
grid-template-rows auto 200px auto, minmax(100px, auto) Définit les lignes et leur taille
gap 20px, 10px 20px Espace entre les cellules (lignes et colonnes)
grid-auto-rows 200px, minmax(100px, auto) Taille par défaut des lignes créées automatiquement
grid-auto-columns 200px Taille par défaut des colonnes créées automatiquement
grid-template-areas "header header header"
"sidebar main main"
"footer footer footer"
Définit des zones nommées pour une mise en page
justify-items start, end, center, stretch Aligne le contenu horizontalement dans les cellules
align-items start, end, center, stretch Aligne le contenu verticalement dans les cellules

10.4. Propriétés des éléments Grid

Propriété Valeurs courantes Effet
grid-column 1 / 3, span 2 Position de l'élément : de la colonne 1 à la colonne 3
grid-row 1 / 3, span 2 Position de l'élément : de la ligne 1 à la ligne 3
grid-area header, 1 / 1 / 3 / 4 Raccourci pour grid-row-start / grid-column-start / grid-row-end / grid-column-end
justify-self start, end, center, stretch Override justify-items pour un élément
align-self start, end, center, stretch Override align-items pour un élément

10.5. Les unités fr, repeat() et minmax()

  • fr : Fraction de l'espace disponible.
    1 f r + 2 f r + 1 f r = 4 f r ,   1 f r = 1 4 × espace _ total
  • repeat() : Répète un motif.
    grid-template-columns: repeat(4, 1fr);   /* 4 colonnes égales */
            grid-template-columns: repeat(3, 200px); /* 3 colonnes de 200px */
  • minmax() : Définit une taille minimale et maximale.
    grid-template-columns: minmax(100px, 1fr); /* Colonne entre 100px et 1fr */

10.6. Exemple complet : Galerie de photos avec Grid

<div class="galerie">
    <div class="item item1">📸 Photo 1</div>
    <div class="item item2">📸 Photo 2</div>
    <div class="item item3">📸 Photo 3</div>
    <div class="item item4">📸 Photo 4</div>
    <div class="item item5">📸 Photo 5</div>
    <div class="item item6">📸 Photo 6</div>
    <div class="item item7">📸 Photo 7</div>
    <div class="item item8">📸 Photo 8</div>
</div>
.galerie {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 200px;
    gap: 15px;
    padding: 20px;
    max-width: 1100px;
    margin: 0 auto;
}

.item {
    background: #4361ee;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    font-size: 18px;
    font-weight: 600;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    cursor: pointer;
}

.item:hover {
    transform: scale(1.03);
    box-shadow: 0 8px 25px rgba(67, 97, 238, 0.3);
}

/* Élément qui prend 2 colonnes et 2 lignes */
.item1 {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
    background: #e74c3c;
}

/* Élément qui prend 2 colonnes en largeur */
.item4 {
    grid-column: 2 / 4;
    background: #f39c12;
}

/* Élément qui prend 2 lignes en hauteur */
.item6 {
    grid-row: span 2;
    background: #2ecc71;
}

/* Élément qui prend 3 colonnes */
.item8 {
    grid-column: span 3;
    background: #9b59b6;
}
📸 1
📸 2
📸 3
📸 4
📸 5
📸 6
📸 7
📸 8

10.7. Flexbox vs Grid — Guide de choix

Cas d'usage Flexbox (1D) CSS Grid (2D)
Navigation ✅ Idéal (alignement horizontal) ❌ Trop puissant
Centrage d'un élément ✅ Parfait (justify-content: center; align-items: center;) ✅ Aussi possible
Galerie de photos ⚠️ Possible avec flex-wrap ✅ Idéal (grille régulière)
Mise en page complexe
(header, sidebar, main, footer)
⚠️ Difficile (plusieurs conteneurs) ✅ Parfait (grid-template-areas)
Alignement vertical ✅ Simple ✅ Simple aussi
Distribution d'espace space-between, space-around ⚠️ Moins intuitif
Ordre des éléments order ⚠️ Plus complexe

 Règle d'or :
Utilisez Flexbox pour les composants (menus, barres d'outils, cartes) et Grid pour la structure globale de la page. Ils se complètent parfaitement.

11. Styliser les liens, les listes et les formulaires

11.1. Styliser les liens (<a>)

Les liens ont 4 états en CSS, correspondant à des pseudo-classes. L'ordre est important : :link:visited:hover:active (mémoire : LOVE HATE).

/* État normal (non visité) */
a:link {
    color: #4361ee;
    text-decoration: none;
}

/* État visité */
a:visited {
    color: #7b1fa2;
}

/* Au survol (souris) */
a:hover {
    color: #e74c3c;
    text-decoration: underline;
}

/* Au moment du clic */
a:active {
    color: #1a1a2e;
}

/* Style alternatif pour les liens dans une navigation */
.menu a {
    color: white;
    text-decoration: none;
    padding: 8px 16px;
    border-radius: 6px;
    transition: background 0.3s;
}

.menu a:hover {
    background: rgba(255,255,255,0.15);
}

.menu a:active {
    background: rgba(255,255,255,0.25);
}

11.2. Styliser les listes

/* Enlever les puces et les marges */
ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

/* Listes à puces personnalisées */
ul.custom {
    list-style-type: square;
    padding-left: 25px;
}

ul.custom li {
    margin-bottom: 8px;
    padding-left: 8px;
}

/* Liste horizontale (menus) */
ul.horizontal {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}

ul.horizontal li {
    background: #eef2ff;
    padding: 8px 18px;
    border-radius: 50px;
    font-weight: 500;
}

/* Puce personnalisée avec ::before */
ul.emoji-puces {
    list-style: none;
    padding: 0;
}

ul.emoji-puces li::before {
    content: "✨ ";
    color: #4361ee;
    font-weight: bold;
}

/* Puce en forme de nombre pour les listes ordonnées */
ol.roman {
    list-style-type: upper-roman;
    padding-left: 30px;
}

11.3. Styliser les formulaires

Les formulaires sont souvent sous-estimés dans leur stylisation. Voici les bonnes pratiques pour des formulaires modernes et accessibles.

<form class="formulaire-moderne">
    <h2>Contactez-nous</h2>

    <div class="champ">
        <label for="nom">Nom complet</label>
        <input type="text" id="nom" placeholder="Jean Dupont" required>
        <span class="aide">Votre nom et prénom</span>
    </div>

    <div class="champ">
        <label for="email">Email</label>
        <input type="email" id="email" placeholder="jean@exemple.com" required>
    </div>

    <div class="champ">
        <label for="message">Message</label>
        <textarea id="message" rows="5" placeholder="Votre message..."></textarea>
    </div>

    <div class="champ">
        <label>Service concerné :</label>
        <select>
            <option value="support">Support technique</option>
            <option value="commercial">Commercial</option>
            <option value="autre">Autre</option>
        </select>
    </div>

    <div class="champ checkbox">
        <input type="checkbox" id="rgpd" required>
        <label for="rgpd">J'accepte la politique de confidentialité</label>
    </div>

    <button type="submit" class="btn-envoyer">
        <span>✉️</span> Envoyer le message
    </button>
</form>
.formulaire-moderne {
    max-width: 550px;
    margin: 0 auto;
    padding: 35px 40px;
    background: white;
    border-radius: 16px;
    box-shadow: 0 10px 40px rgba(0,0,0,0.08);
}

.formulaire-moderne h2 {
    margin-top: 0;
    margin-bottom: 25px;
    color: #1a1a2e;
    font-size: 26px;
}

.champ {
    margin-bottom: 22px;
}

.champ label {
    display: block;
    font-weight: 600;
    margin-bottom: 6px;
    color: #2d3436;
    font-size: 14px;
}

.champ input,
.champ textarea,
.champ select {
    width: 100%;
    padding: 12px 16px;
    border: 2px solid #e0e0e0;
    border-radius: 8px;
    font-size: 16px;
    font-family: inherit;
    transition: border-color 0.3s, box-shadow 0.3s;
    background: #fafafa;
}

.champ input:focus,
.champ textarea:focus,
.champ select:focus {
    border-color: #4361ee;
    box-shadow: 0 0 0 4px rgba(67, 97, 238, 0.15);
    outline: none;
    background: white;
}

.champ textarea {
    resize: vertical;
    min-height: 100px;
}

.champ .aide {
    display: block;
    font-size: 13px;
    color: #6c757d;
    margin-top: 4px;
}

.champ.checkbox {
    display: flex;
    align-items: center;
    gap: 10px;
}

.champ.checkbox input {
    width: auto;
    margin: 0;
    accent-color: #4361ee;
    width: 18px;
    height: 18px;
    cursor: pointer;
}

.champ.checkbox label {
    margin: 0;
    font-weight: 400;
    cursor: pointer;
}

.btn-envoyer {
    width: 100%;
    padding: 14px;
    background: #4361ee;
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 18px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.3s, transform 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

.btn-envoyer:hover {
    background: #3a0ca3;
    transform: translateY(-2px);
}

.btn-envoyer:active {
    transform: scale(0.97);
}

/* État de validation des champs */
.champ input:valid {
    border-color: #2ecc71;
}

.champ input:invalid:not(:placeholder-shown) {
    border-color: #e74c3c;
}
⚠️ Accessibilité des formulaires :
  • Utilisez toujours <label> avec for correspondant à l'id du champ.
  • Placez les messages d'erreur à proximité du champ concerné.
  • Utilisez autocomplete pour faciliter le remplissage.
  • Indiquez les champs obligatoires avec required ou un astérisque visible.

12. Comprendre les bases du responsive design

12.1. Qu'est-ce que le responsive design ?

Le responsive design (ou design adaptatif) est une approche de conception web qui vise à créer des sites qui s'affichent correctement sur tous les types d'écrans : ordinateur, tablette, smartphone, télévision, etc.

Il a été popularisé par Ethan Marcotte en 2010 et repose sur trois piliers :

  • Les grilles fluides : utilisation de pourcentages plutôt que de pixels fixes.
  • Les images flexibles : images qui s'adaptent à la taille du conteneur.
  • Les media queries : points de rupture où le design change.

12.2. La balise viewport

Sans la balise viewport, les mobiles affichent les pages comme si elles étaient sur un écran d'ordinateur, ce qui oblige l'utilisateur à zoomer. La balise viewport résout ce problème.

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Explication des paramètres :

  • width=device-width : La largeur de la page est égale à la largeur de l'écran.
  • initial-scale=1.0 : Niveau de zoom initial de 100%.
  • maximum-scale=1.0 (optionnel) : Empêche le zoom (déconseillé pour l'accessibilité).
  • user-scalable=yes (optionnel) : Permet à l'utilisateur de zoomer (recommandé).

📐 Relation entre la taille de l'écran et la résolution :

densité _ pixels = nombre _ pixels _ réels × 160 dpi largeur _ écran _ en _ pouces

Exemple : un écran de 375px avec un facteur d'échelle de 2× équivaut à 750px physiques.

12.3. Les unités relatives

Unité Description Exemple Calcul
% Pourcentage du parent width: 80%; 80% de la largeur du parent
em Relatif à la taille de police du parent font-size: 2em; 2× la taille de police du parent
rem Relatif à la taille de police racine (<html>) font-size: 1.5rem; 1.5× la taille de police racine
vw 1% de la largeur de la fenêtre width: 50vw; 50% de la largeur du viewport
vh 1% de la hauteur de la fenêtre height: 100vh; 100% de la hauteur du viewport
vmin 1% de la plus petite dimension font-size: 2vmin; 2% de la plus petite dimension
vmax 1% de la plus grande dimension font-size: 2vmax; 2% de la plus grande dimension
💡 Bonne pratique : Utilisez rem pour les tailles de police et les espacements. Cela permet à l'utilisateur de modifier la taille de la police via les paramètres de son navigateur. La taille racine par défaut est généralement 16px.

12.4. Les media queries

Les media queries permettent d'appliquer des styles CSS spécifiques selon les caractéristiques de l'appareil (largeur, hauteur, orientation, etc.).

/* ============================================= */
/* APPROCHE MOBILE-FIRST (recommandée)           */
/* ============================================= */

/* Styles pour TOUS les écrans (base mobile) */
body {
    font-size: 16px;
    padding: 10px;
}

h1 {
    font-size: 24px;
}

.grille {
    grid-template-columns: 1fr;
    gap: 15px;
}

/* ============================================= */
/* Tablettes (≥ 768px)                          */
/* ============================================= */
@media (min-width: 768px) {
    body {
        font-size: 18px;
        padding: 20px;
    }

    h1 {
        font-size: 32px;
    }

    .grille {
        grid-template-columns: repeat(2, 1fr);
        gap: 20px;
    }
}

/* ============================================= */
/* Ordinateurs (≥ 1024px)                      */
/* ============================================= */
@media (min-width: 1024px) {
    body {
        font-size: 20px;
        padding: 30px;
    }

    h1 {
        font-size: 42px;
    }

    .grille {
        grid-template-columns: repeat(4, 1fr);
        gap: 25px;
    }
}

/* ============================================= */
/* Grands écrans (≥ 1440px)                    */
/* ============================================= */
@media (min-width: 1440px) {
    body {
        max-width: 1400px;
        margin: 0 auto;
    }
}

/* ============================================= */
/* Orientation paysage sur mobile               */
/* ============================================= */
@media (max-width: 768px) and (orientation: landscape) {
    .banniere {
        height: 60vh;
    }
}

/* ============================================= */
/* Impression                                   */
/* ============================================= */
@media print {
    nav, .publicite {
        display: none;
    }
    body {
        font-size: 12pt;
        color: black;
        background: white;
    }
}
✅ Approche "Mobile-First" :
  • On commence par écrire le CSS pour les mobiles (taille d'écran la plus petite).
  • On utilise des min-width pour ajouter des styles pour les écrans plus grands.
  • Avantages : performance (moins de CSS à charger sur mobile), meilleure accessibilité.
  • Cette approche est aujourd'hui la référence en matière de responsive design.

12.5. Exemple pratique : Menu responsive avec burger

<!-- HTML -->
<nav class="nav-responsive">
    <div class="logo">🚀 MonSite</div>

    <input type="checkbox" id="burger" class="burger-input">
    <label for="burger" class="burger-label">
        <span></span>
        <span></span>
        <span></span>
    </label>

    <ul class="nav-links">
        <li><a href="#">Accueil</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">À propos</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>
/* CSS */
.nav-responsive {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 20px;
    background: #1a1a2e;
    color: white;
    position: relative;
}

.logo {
    font-size: 22px;
    font-weight: 700;
}

.nav-links {
    display: flex;
    list-style: none;
    gap: 25px;
}

.nav-links a {
    color: rgba(255,255,255,0.8);
    text-decoration: none;
    padding: 6px 12px;
    border-radius: 6px;
    transition: background 0.3s;
}

.nav-links a:hover {
    background: rgba(255,255,255,0.12);
    color: white;
}

/* Cacher le burger sur desktop */
.burger-input,
.burger-label {
    display: none;
}

/* ============================================= */
/* VERSION MOBILE                               */
/* ============================================= */
@media (max-width: 768px) {
    .burger-label {
        display: flex;
        flex-direction: column;
        gap: 5px;
        cursor: pointer;
        padding: 5px;
        z-index: 10;
    }

    .burger-label span {
        display: block;
        width: 28px;
        height: 3px;
        background: white;
        border-radius: 2px;
        transition: 0.3s ease;
    }

    /* Animation du burger en croix */
    .burger-input:checked + .burger-label span:nth-child(1) {
        transform: rotate(45deg) translate(5px, 6px);
    }

    .burger-input:checked + .burger-label span:nth-child(2) {
        opacity: 0;
    }

    .burger-input:checked + .burger-label span:nth-child(3) {
        transform: rotate(-45deg) translate(5px, -6px);
    }

    /* Menu caché par défaut */
    .nav-links {
        display: none;
        flex-direction: column;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: #1a1a2e;
        padding: 20px;
        gap: 5px;
        border-top: 1px solid rgba(255,255,255,0.1);
        box-shadow: 0 10px 30px rgba(0,0,0,0.3);
    }

    .nav-links li {
        width: 100%;
    }

    .nav-links a {
        display: block;
        padding: 12px 16px;
        width: 100%;
        border-radius: 8px;
        font-size: 18px;
    }

    .nav-links a:hover {
        background: rgba(67, 97, 238, 0.2);
    }

    /* Afficher le menu quand la checkbox est cochée */
    .burger-input:checked ~ .nav-links {
        display: flex;
    }
}

13. Ajouter des animations et transitions

13.1. Les transitions

Les transitions permettent de passer en douceur d'une valeur CSS à une autre lors d'un changement d'état (survol, focus, etc.).

Syntaxe :

transition: propriété durée fonction délai;
Paramètre Valeurs Explication
Propriété all, color, transform, opacity La propriété CSS à animer
Durée 0.3s, 300ms, 2s Durée de la transition
Fonction ease, linear, ease-in, ease-out, ease-in-out, cubic-bezier() Courbe d'accélération
Délai 0s, 0.5s, 1s Temps d'attente avant le début
/* Transition sur plusieurs propriétés */
.bouton {
    background: #4361ee;
    color: white;
    padding: 12px 30px;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    cursor: pointer;

    /* Transition sur background et transform */
    transition: background 0.3s ease, transform 0.2s ease-out;
}

.bouton:hover {
    background: #3a0ca3;
    transform: scale(1.05);
}

.bouton:active {
    transform: scale(0.95);
}

📐 Fonctions de transition (courbes de Bézier) :

B ( t ) = ( 1 - t ) 3 P 0 + 3 ( 1 - t ) 2 t P 1 + 3 ( 1 - t ) t 2 P 2 + t 3 P 3 ,   t ∈ [ 0 , 1 ]

Les points de contrôle définissent l'accélération de la transition.

13.2. Les animations keyframes

Les animations permettent de créer des séquences d'étapes (keyframes) pour des mouvements plus complexes et répétitifs.

Syntaxe :

@keyframes nom-de-lanimation {
    0%   { /* styles au début */ }
    50%  { /* styles à mi-parcours */ }
    100% { /* styles à la fin */ }
}

.element {
    animation: nom-de-lanimation 2s ease-in-out infinite;
}
/* Animation de pulsation */
@keyframes pulse {
    0% {
        transform: scale(1);
        opacity: 1;
    }
    50% {
        transform: scale(1.08);
        opacity: 0.8;
    }
    100% {
        transform: scale(1);
        opacity: 1;
    }
}

.pulse {
    animation: pulse 1.5s ease-in-out infinite;
}

/* Animation de chargement (spinner) */
@keyframes spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

.spinner {
    animation: spin 1s linear infinite;
}

/* Animation d'apparition en fondu */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.fade-in {
    animation: fadeInUp 0.6s ease-out forwards;
}

/* Animation de rebond */
@keyframes bounce {
    0%, 100% {
        transform: translateY(0);
    }
    30% {
        transform: translateY(-40px);
    }
    50% {
        transform: translateY(0);
    }
    70% {
        transform: translateY(-20px);
    }
    85% {
        transform: translateY(0);
    }
    95% {
        transform: translateY(-8px);
    }
}

.bounce {
    animation: bounce 1.2s ease infinite;
}

13.3. Exemple de carte animée

<div class="carte-interactive">
    <img src="image.jpg" alt="Image de la carte">
    <div class="contenu-carte">
        <h3>Titre de la carte</h3>
        <p>Description de la carte avec des détails intéressants.</p>
        <a href="#" class="btn-carte">En savoir plus →</a>
    </div>
</div>
.carte-interactive {
    background: white;
    border-radius: 16px;
    overflow: hidden;
    max-width: 340px;
    box-shadow: 0 4px 15px rgba(0,0,0,0.08);
    transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),
                box-shadow 0.4s ease;
}

.carte-interactive:hover {
    transform: translateY(-12px) scale(1.01);
    box-shadow: 0 20px 50px rgba(0,0,0,0.15);
}

.carte-interactive img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    transition: transform 0.6s ease;
}

.carte-interactive:hover img {
    transform: scale(1.06);
}

.contenu-carte {
    padding: 20px 24px 24px;
}

.contenu-carte h3 {
    margin: 0 0 8px 0;
    font-size: 20px;
    color: #1a1a2e;
}

.contenu-carte p {
    color: #4a4e69;
    font-size: 14px;
    line-height: 1.6;
    margin-bottom: 16px;
}

.btn-carte {
    display: inline-block;
    padding: 10px 24px;
    background: #4361ee;
    color: white;
    text-decoration: none;
    border-radius: 50px;
    font-weight: 600;
    transition: background 0.3s, transform 0.2s;
}

.btn-carte:hover {
    background: #3a0ca3;
    transform: translateX(4px);
}

Partie 3 : Exercice pratique complet

14. Page de présentation de services — Projet complet

14.1. Objectif du projet

Vous allez créer une page de présentation de services pour une agence web. Ce projet intègre toutes les notions vues dans ce cours :

  • Structure HTML sémantique
  • Navigation avec Flexbox
  • Grille de services avec CSS Grid
  • Cartes animées
  • Formulaire de contact stylisé
  • Responsive design (mobile-first)
  • Transitions et animations

14.2. Structure de la page

+-----------------------------------------------------+ | 🚀 MonAgence Accueil | Services | Contact | +-----------------------------------------------------+ | | | ╔═══════════════════════════════════════════════╗ | | ║ Des solutions numériques sur mesure ║ | | ║ Nous créons des expériences web uniques ║ | | ║ [ 🚀 Commencer ] ║ | | ╚═══════════════════════════════════════════════╝ | | | | ┌─────────┐ ┌─────────┐ ┌─────────┐ | | │ 💻 │ │ 📱 │ │ 🎨 │ | | │ Dévelop. │ │ Mobile │ │ Design │ | | │ web │ │ │ │ UX/UI │ | | └─────────┘ └─────────┘ └─────────┘ | | | | ┌─────────────────────────────────────────────┐ | | │ Contactez-nous │ | | │ Nom : [____________________] │ | | │ Email : [____________________] │ | | │ Message: [____________________] │ | | │ [ ✉️ Envoyer ] │ | | └─────────────────────────────────────────────┘ | | | | © 2026 MonAgence - Tous droits réservés | +-----------------------------------------------------+

14.3. Code complet — HTML

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MonAgence — Services numériques</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <!-- ============================================= -->
    <!-- NAVBAR                                      -->
    <!-- ============================================= -->
    <nav class="navbar">
        <div class="logo">🚀 MonAgence</div>

        <input type="checkbox" id="menu-toggle" class="menu-toggle">
        <label for="menu-toggle" class="menu-hamburger">
            <span></span>
            <span></span>
            <span></span>
        </label>

        <ul class="nav-links">
            <li><a href="#" class="active">Accueil</a></li>
            <li><a href="#services">Services</a></li>
            <li><a href="#contact">Contact</a></li>
        </ul>
    </nav>

    <!-- ============================================= -->
    <!-- HERO SECTION                                 -->
    <!-- ============================================= -->
    <header class="hero" id="accueil">
        <div class="hero-contenu">
            <h1>Des solutions numériques <span>sur mesure</span></h1>
            <p>Nous créons des expériences web uniques qui transforment vos idées en réalité.</p>
            <a href="#contact" class="btn-cta">
                🚀 Commencer un projet
            </a>
        </div>
        <div class="hero-statistiques">
            <div class="stat">
                <span class="stat-nombre">150+</span>
                <span class="stat-label">Projets réalisés</span>
            </div>
            <div class="stat">
                <span class="stat-nombre">98%</span>
                <span class="stat-label">Clients satisfaits</span>
            </div>
            <div class="stat">
                <span class="stat-nombre">4.9★</span>
                <span class="stat-label">Avis clients</span>
            </div>
        </div>
    </header>

    <!-- ============================================= -->
    <!-- SERVICES SECTION                             -->
    <!-- ============================================= -->
    <section class="services" id="services">
        <div class="services-header">
            <span class="services-badge">Nos compétences</span>
            <h2>Ce que nous faisons de mieux</h2>
            <p>Des services digitaux conçus pour répondre à vos besoins spécifiques.</p>
        </div>

        <div class="grille-services">
            <div class="service-card">
                <div class="service-icone">💻</div>
                <h3>Développement web</h3>
                <p>Création de sites vitrines, e-commerces et applications web sur mesure.</p>
                <a href="#" class="service-lien">En savoir plus →</a>
            </div>

            <div class="service-card">
                <div class="service-icone">📱</div>
                <h3>Applications mobiles</h3>
                <p>Développement d'applications natives et hybrides pour iOS et Android.</p>
                <a href="#" class="service-lien">En savoir plus →</a>
            </div>

            <div class="service-card">
                <div class="service-icone">🎨</div>
                <h3>Design UX/UI</h3>
                <p>Conception d'interfaces modernes, intuitives et centrées sur l'utilisateur.</p>
                <a href="#" class="service-lien">En savoir plus →</a>
            </div>

            <div class="service-card">
                <div class="service-icone">🔍</div>
                <h3>Référencement SEO</h3>
                <p>Optimisation de votre visibilité sur les moteurs de recherche.</p>
                <a href="#" class="service-lien">En savoir plus →</a>
            </div>

            <div class="service-card">
                <div class="service-icone">📊</div>
                <h3>Analyse de données</h3>
                <p>Tableaux de bord et analyses pour piloter votre stratégie digitale.</p>
                <a href="#" class="service-lien">En savoir plus →</a>
            </div>

            <div class="service-card">
                <div class="service-icone">⚡</div>
                <h3>Maintenance & support</h3>
                <p>Accompagnement continu et maintenance technique de vos projets.</p>
                <a href="#" class="service-lien">En savoir plus →</a>
            </div>
        </div>
    </section>

    <!-- ============================================= -->
    <!-- CONTACT SECTION                             -->
    <!-- ============================================= -->
    <section class="contact" id="contact">
        <div class="contact-conteneur">
            <div class="contact-info">
                <span class="contact-badge">Contact</span>
                <h2>Parlons de votre projet</h2>
                <p>Une question ? Un projet en tête ? N'hésitez pas à nous contacter.</p>
                <ul class="contact-details">
                    <li>📧 <a href="mailto:contact@monagence.com">contact@monagence.com</a></li>
                    <li>📞 <a href="tel:+33123456789">01 23 45 67 89</a></li>
                    <li>📍 123 rue du Web, 75000 Paris</li>
                </ul>
            </div>

            <form class="contact-form">
                <div class="form-row">
                    <div class="form-group">
                        <label for="nom">Nom complet</label>
                        <input type="text" id="nom" placeholder="Jean Dupont" required>
                    </div>
                    <div class="form-group">
                        <label for="email">Email</label>
                        <input type="email" id="email" placeholder="jean@email.com" required>
                    </div>
                </div>
                <div class="form-group">
                    <label for="sujet">Sujet</label>
                    <select id="sujet">
                        <option value="devis">Demande de devis</option>
                        <option value="information">Demande d'information</option>
                        <option value="autre">Autre</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="message">Message</label>
                    <textarea id="message" rows="5" placeholder="Décrivez votre projet..." required></textarea>
                </div>
                <div class="form-checkbox">
                    <input type="checkbox" id="rgpd" required>
                    <label for="rgpd">J'accepte la politique de confidentialité</label>
                </div>
                <button type="submit" class="btn-submit">
                    ✉️ Envoyer le message
                </button>
            </form>
        </div>
    </section>

    <!-- ============================================= -->
    <!-- FOOTER                                      -->
    <!-- ============================================= -->
    <footer class="footer">
        <div class="footer-contenu">
            <div class="footer-colonne">
                <h4>🚀 MonAgence</h4>
                <p>Agence digitale créative au service de vos projets web.</p>
            </div>
            <div class="footer-colonne">
                <h4>Liens rapides</h4>
                <ul>
                    <li><a href="#">Accueil</a></li>
                    <li><a href="#services">Services</a></li>
                    <li><a href="#contact">Contact</a></li>
                </ul>
            </div>
            <div class="footer-colonne">
                <h4>Suivez-nous</h4>
                <div class="footer-reseaux">
                    <a href="#">🐦 Twitter</a>
                    <a href="#">📘 LinkedIn</a>
                    <a href="#">📸 Instagram</a>
                </div>
            </div>
        </div>
        <div class="footer-bottom">
            <p>&copy; 2026 MonAgence — Tous droits réservés.</p>
        </div>
    </footer>

</body>
</html>

14.4. Code complet — CSS

/* ============================================= */
/* RESET ET BASE                                 */
/* ============================================= */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    color: #1a1a2e;
    background: #f8f9fc;
    line-height: 1.7;
}

/* ============================================= */
/* NAVBAR                                        */
/* ============================================= */
.navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 30px;
    background: #1a1a2e;
    color: white;
    position: sticky;
    top: 0;
    z-index: 100;
    box-shadow: 0 4px 20px rgba(0,0,0,0.2);
}

.logo {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.5px;
}

.nav-links {
    display: flex;
    list-style: none;
    gap: 30px;
}

.nav-links a {
    color: rgba(255,255,255,0.7);
    text-decoration: none;
    font-weight: 500;
    padding: 6px 0;
    border-bottom: 2px solid transparent;
    transition: color 0.3s, border-color 0.3s;
}

.nav-links a:hover,
.nav-links a.active {
    color: white;
    border-bottom-color: #4361ee;
}

.menu-toggle,
.menu-hamburger {
    display: none;
}

/* ============================================= */
/* HERO SECTION                                  */
/* ============================================= */
.hero {
    background: linear-gradient(135deg, #1a1a2e 0%, #3a0ca3 50%, #4361ee 100%);
    color: white;
    text-align: center;
    padding: 80px 20px 60px;
}

.hero-contenu h1 {
    font-size: 48px;
    font-weight: 800;
    margin-bottom: 20px;
    line-height: 1.2;
}

.hero-contenu h1 span {
    color: #f7d794;
}

.hero-contenu p {
    font-size: 20px;
    max-width: 600px;
    margin: 0 auto 30px;
    opacity: 0.9;
}

.btn-cta {
    display: inline-block;
    padding: 16px 40px;
    background: white;
    color: #1a1a2e;
    text-decoration: none;
    border-radius: 50px;
    font-weight: 700;
    font-size: 18px;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.btn-cta:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 15px 35px rgba(0,0,0,0.25);
}

.hero-statistiques {
    display: flex;
    justify-content: center;
    gap: 60px;
    margin-top: 50px;
}

.stat {
    display: flex;
    flex-direction: column;
}

.stat-nombre {
    font-size: 32px;
    font-weight: 800;
    color: #f7d794;
}

.stat-label {
    font-size: 14px;
    opacity: 0.8;
}

/* ============================================= */
/* SERVICES SECTION                             */
/* ============================================= */
.services {
    padding: 70px 30px;
    max-width: 1200px;
    margin: 0 auto;
}

.services-header {
    text-align: center;
    margin-bottom: 50px;
}

.services-badge {
    display: inline-block;
    background: #eef2ff;
    color: #4361ee;
    padding: 4px 18px;
    border-radius: 50px;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

.services-header h2 {
    font-size: 38px;
    margin: 12px 0 8px;
}

.services-header p {
    color: #4a4e69;
    font-size: 18px;
    max-width: 500px;
    margin: 0 auto;
}

.grille-services {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
}

.service-card {
    background: white;
    padding: 32px 28px;
    border-radius: 16px;
    text-align: center;
    box-shadow: 0 4px 15px rgba(0,0,0,0.05);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    border: 1px solid rgba(0,0,0,0.04);
}

.service-card:hover {
    transform: translateY(-8px);
    box-shadow: 0 20px 50px rgba(67, 97, 238, 0.12);
}

.service-icone {
    font-size: 48px;
    margin-bottom: 16px;
}

.service-card h3 {
    font-size: 20px;
    margin-bottom: 10px;
    color: #1a1a2e;
}

.service-card p {
    color: #4a4e69;
    font-size: 14px;
    margin-bottom: 16px;
}

.service-lien {
    color: #4361ee;
    text-decoration: none;
    font-weight: 600;
    transition: color 0.3s;
}

.service-lien:hover {
    color: #3a0ca3;
}

/* ============================================= */
/* CONTACT SECTION                              */
/* ============================================= */
.contact {
    background: #1a1a2e;
    color: white;
    padding: 70px 30px;
}

.contact-conteneur {
    max-width: 1100px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr 1.5fr;
    gap: 50px;
}

.contact-badge {
    display: inline-block;
    background: rgba(67, 97, 238, 0.2);
    color: #4361ee;
    padding: 4px 18px;
    border-radius: 50px;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

.contact-info h2 {
    font-size: 36px;
    margin: 12px 0 8px;
}

.contact-info p {
    opacity: 0.8;
    margin-bottom: 25px;
}

.contact-details {
    list-style: none;
    padding: 0;
}

.contact-details li {
    margin-bottom: 12px;
}

.contact-details a {
    color: #4361ee;
    text-decoration: none;
}

.contact-details a:hover {
    text-decoration: underline;
}

.contact-form {
    background: white;
    color: #1a1a2e;
    padding: 35px 40px;
    border-radius: 16px;
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

.form-group {
    margin-bottom: 20px;
}

.form-group label {
    display: block;
    font-weight: 600;
    font-size: 14px;
    margin-bottom: 6px;
}

.form-group input,
.form-group textarea,
.form-group select {
    width: 100%;
    padding: 12px 16px;
    border: 2px solid #e0e0e0;
    border-radius: 8px;
    font-size: 16px;
    font-family: inherit;
    transition: border-color 0.3s, box-shadow 0.3s;
    background: #fafafa;
}

.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
    border-color: #4361ee;
    box-shadow: 0 0 0 4px rgba(67, 97, 238, 0.12);
    outline: none;
    background: white;
}

.form-group textarea {
    resize: vertical;
    min-height: 120px;
}

.form-checkbox {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 22px;
}

.form-checkbox input {
    width: 18px;
    height: 18px;
    accent-color: #4361ee;
    cursor: pointer;
}

.form-checkbox label {
    font-size: 14px;
    cursor: pointer;
}

.btn-submit {
    width: 100%;
    padding: 14px;
    background: #4361ee;
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 18px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.3s, transform 0.2s;
}

.btn-submit:hover {
    background: #3a0ca3;
    transform: translateY(-2px);
}

.btn-submit:active {
    transform: scale(0.97);
}

/* ============================================= */
/* FOOTER                                       */
/* ============================================= */
.footer {
    background: #0d0d1a;
    color: rgba(255,255,255,0.7);
    padding: 40px 30px 0;
}

.footer-contenu {
    max-width: 1100px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: 40px;
    padding-bottom: 30px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}

.footer-colonne h4 {
    color: white;
    font-size: 18px;
    margin-bottom: 14px;
}

.footer-colonne p {
    font-size: 14px;
    line-height: 1.6;
}

.footer-colonne ul {
    list-style: none;
    padding: 0;
}

.footer-colonne ul li {
    margin-bottom: 8px;
}

.footer-colonne ul a {
    color: rgba(255,255,255,0.6);
    text-decoration: none;
    transition: color 0.3s;
}

.footer-colonne ul a:hover {
    color: white;
}

.footer-reseaux {
    display: flex;
    gap: 15px;
    flex-wrap: wrap;
}

.footer-reseaux a {
    color: rgba(255,255,255,0.6);
    text-decoration: none;
    transition: color 0.3s;
}

.footer-reseaux a:hover {
    color: white;
}

.footer-bottom {
    text-align: center;
    padding: 20px;
    font-size: 14px;
    opacity: 0.6;
}

/* ============================================= */
/* RESPONSIVE — TABLETTES                       */
/* ============================================= */
@media (max-width: 992px) {
    .grille-services {
        grid-template-columns: repeat(2, 1fr);
    }

    .contact-conteneur {
        grid-template-columns: 1fr;
        gap: 30px;
    }

    .footer-contenu {
        grid-template-columns: 1fr 1fr;
    }
}

/* ============================================= */
/* RESPONSIVE — MOBILES                         */
/* ============================================= */
@media (max-width: 768px) {
    /* Navbar burger */
    .menu-hamburger {
        display: flex;
        flex-direction: column;
        gap: 5px;
        cursor: pointer;
        padding: 5px;
        z-index: 10;
    }

    .menu-hamburger span {
        display: block;
        width: 28px;
        height: 3px;
        background: white;
        border-radius: 2px;
        transition: 0.3s ease;
    }

    .menu-toggle:checked + .menu-hamburger span:nth-child(1) {
        transform: rotate(45deg) translate(5px, 6px);
    }

    .menu-toggle:checked + .menu-hamburger span:nth-child(2) {
        opacity: 0;
    }

    .menu-toggle:checked + .menu-hamburger span:nth-child(3) {
        transform: rotate(-45deg) translate(5px, -6px);
    }

    .nav-links {
        display: none;
        flex-direction: column;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: #1a1a2e;
        padding: 20px;
        gap: 5px;
        border-top: 1px solid rgba(255,255,255,0.06);
    }

    .nav-links li {
        width: 100%;
    }

    .nav-links a {
        display: block;
        padding: 12px 16px;
        border-bottom: none;
        border-radius: 8px;
        font-size: 18px;
    }

    .nav-links a:hover {
        background: rgba(67, 97, 238, 0.15);
        border-bottom-color: transparent;
    }

    .menu-toggle:checked ~ .nav-links {
        display: flex;
    }

    /* Hero */
    .hero-contenu h1 {
        font-size: 30px;
    }

    .hero-contenu p {
        font-size: 17px;
    }

    .hero-statistiques {
        flex-direction: column;
        gap: 20px;
        align-items: center;
    }

    /* Services */
    .grille-services {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    .services-header h2 {
        font-size: 28px;
    }

    /* Contact */
    .form-row {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .contact-form {
        padding: 25px 20px;
    }

    /* Footer */
    .footer-contenu {
        grid-template-columns: 1fr;
        gap: 25px;
    }
}

@media (max-width: 480px) {
    .navbar {
        padding: 12px 16px;
    }

    .logo {
        font-size: 20px;
    }

    .hero {
        padding: 50px 16px 40px;
    }

    .hero-contenu h1 {
        font-size: 26px;
    }

    .btn-cta {
        padding: 14px 28px;
        font-size: 16px;
    }

    .services {
        padding: 40px 16px;
    }

    .contact {
        padding: 40px 16px;
    }
}

Last modified: Saturday, 8 August 2026, 3:58 PM