Partie 2 — Mise en page avancée avec CSS Box Model, Flexbox, Grid, Formulaires, Responsive, Animations
📑 Sommaire de la Partie 2
8. Comprendre et utiliser 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 fondamental qui définit comment ces boîtes sont dimensionnées et comment l'espace est calculé autour d'elles. C'est la base de toute mise en page en CSS.
Le Box Model se compose de 4 couches (de l'intérieur vers l'extérieur) :
- Content (contenu) : Le contenu réel de l'élément (texte, image, etc.).
- Padding (espace interne) : L'espace entre le contenu et la bordure.
- Border (bordure) : La ligne qui entoure le padding.
- Margin (marge externe) : L'espace entre la bordure et les autres éléments.
8.2. Les propriétés du Box Model en détail
| Propriété | Description | Exemple | Valeurs typiques |
|---|---|---|---|
content |
Le contenu interne | width: 200px; |
px, %, em, rem, auto |
padding |
Espace intérieur entre contenu et bordure | padding: 20px; |
padding: 10px 20px; (haut/bas, gauche/droite) |
border |
La bordure autour du 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.2.1. Les raccourcis (shorthands)
Pour padding et margin, il existe des syntaxes raccourcies qui permettent de définir plusieurs côtés en une seule ligne :
/* 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.3. La propriété box-sizing — le concept le plus important
Par défaut (box-sizing: content-box), la largeur totale d'une boîte est :
width: 200px avec padding: 20px et border: 2px aura une largeur réelle de 244px ! Cela rend les calculs de mise en page très difficiles, surtout en responsive.La solution : utiliser box-sizing: border-box, qui inclut le padding et la bordure dans la largeur définie.
/* Règle universelle — À mettre en premier dans votre CSS */
* {
box-sizing: border-box;
}
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, Foundation, etc.).
- Évite les surprises lors de l'ajout de padding ou de bordures.
8.4. Le phénomène de fusion des marges (margin collapsing)
En CSS, les marges verticales de deux éléments adjacents se fusionnent. La marge résultante est égale à la plus grande des deux marges.
/* Exemple de fusion des marges */
.element-a {
margin-bottom: 30px;
}
.element-b {
margin-top: 20px;
}
/* L'espace entre A et B sera de 30px, pas 50px ! */
- Utiliser
paddingà la place demargin. - Ajouter
borderoupaddingsur le parent. - Utiliser
display: flexoudisplay: gridsur le parent. - Utiliser
overflow: hiddenouoverflow: autosur le parent.
9. Créer des mises en page flexibles avec Flexbox
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 radicalement l'alignement et la distribution d'espace.
Flexbox permet de répartir l'espace et d'aligner les éléments dans un conteneur sur un seul axe (horizontal ou vertical). C'est parfait pour :
- Les menus de navigation (alignement horizontal).
- Les barres d'outils.
- Les cartes avec disposition flexible.
- Le centrage vertical et horizontal.
- Les listes d'éléments de taille variable.
9.2. Les deux axes de Flexbox
- Axe principal (main axis) : Direction dans laquelle les éléments sont disposés.
- Axe secondaire (cross axis) : Direction perpendiculaire à l'axe principal.
9.3. Activation de Flexbox
.conteneur-flex {
display: flex; /* Active le mode Flexbox */
}
9.4. 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, space-around |
Aligne les lignes sur l'axe secondaire (quand flex-wrap: wrap) |
9.4.1. Visualisation de justify-content
🎯 Les différentes valeurs de justify-content :
flex-start→ éléments alignés au début (à gauche).flex-end→ éléments alignés à la fin (à droite).center→ éléments centrés.space-between→ espace égal entre les éléments (1er à gauche, dernier à droite).space-around→ espace égal autour de chaque élément.space-evenly→ espace parfaitement égal partout.
9.5. 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.6. Exemple complet : Barre de navigation 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;
}
.menu {
display: flex;
list-style: none;
gap: 30px;
}
.menu a {
color: rgba(255,255,255,0.8);
text-decoration: none;
font-weight: 500;
transition: color 0.3s, border-color 0.3s;
border-bottom: 2px solid transparent;
padding: 6px 0;
}
.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);
}
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. gap est supporté dans tous les navigateurs modernes.10. Créer des mises en page en 2D avec CSS Grid
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.
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" |
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. Les unités spécifiques à Grid
10.4.1. L'unité fr (fraction)
L'unité fr représente une fraction de l'espace disponible dans le conteneur Grid. C'est l'équivalent de "parts" dans un partage équitable.
Répartition de l'espace avec les unités fr
Chaque 1fr = 14 de l'espace total
/* 3 colonnes : 1fr, 2fr, 1fr */
grid-template-columns: 1fr 2fr 1fr;
/* 4 colonnes égales */
grid-template-columns: repeat(4, 1fr);
/* 2 colonnes : 200px, puis le reste */
grid-template-columns: 200px 1fr;
10.4.2. La fonction repeat()
repeat() permet de répéter un motif de colonnes ou de lignes sans avoir à le réécrire plusieurs fois.
/* Équivalent à : 1fr 1fr 1fr 1fr 1fr */
grid-template-columns: repeat(5, 1fr);
/* Équivalent à : 100px 200px 100px 200px 100px 200px */
grid-template-columns: repeat(3, 100px 200px);
/* Combinaison avec d'autres valeurs */
grid-template-columns: 200px repeat(3, 1fr) 100px;
10.4.3. La fonction minmax()
minmax() définit une taille minimale et une taille maximale pour une colonne ou une ligne.
/* Colonne qui fait au moins 100px et au plus 1fr */
grid-template-columns: minmax(100px, 1fr);
/* Ligne qui fait au moins 50px et au plus 200px */
grid-template-rows: minmax(50px, 200px);
/* Avec auto (taille naturelle) */
grid-template-columns: minmax(150px, auto) 1fr;
10.5. 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.6. Exemple complet : Galerie de photos avec Grid
<div class="galerie">
<div class="item item1">📸 1</div>
<div class="item item2">📸 2</div>
<div class="item item3">📸 3</div>
<div class="item item4">📸 4</div>
<div class="item item5">📸 5</div>
<div class="item item6">📸 6</div>
<div class="item item7">📸 7</div>
<div class="item item8">📸 8</div>
</div>
.galerie {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 180px;
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: 20px;
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;
}
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 |
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);
}
"Love Hate" est un moyen facile de s'en souvenir !
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 — bonnes pratiques
Les formulaires sont souvent sous-estimés dans leur stylisation. Voici les bonnes pratiques pour des formulaires modernes et accessibles.
- Utilisez toujours
<label>avecforcorrespondant à l'iddu champ. - Placez les messages d'erreur à proximité du champ concerné.
- Utilisez
autocompletepour faciliter le remplissage. - Indiquez les champs obligatoires avec
requiredou un astérisque visible. - Utilisez
aria-describedbypour lier les messages d'aide.
<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 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;
}
12. Comprendre le 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 _ poucesExemple : 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 |
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;
}
}
/* ============================================= */
/* Impression */
/* ============================================= */
@media print {
nav, .publicite {
display: none;
}
body {
font-size: 12pt;
color: black;
background: white;
}
}
- On commence par écrire le CSS pour les mobiles (taille d'écran la plus petite).
- On utilise des
min-widthpour 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 : 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);
}
📝 Exercices pratiques
Exercice 1 — Box Model
Créez un élément div avec les caractéristiques suivantes :
- Largeur : 300px
- Padding : 20px
- Bordure : 3px solide noire
- Marge : 15px
- Couleur de fond :
#eef2ff
Question : Quelle est la largeur totale de l'élément avec box-sizing: content-box ? Et avec box-sizing: border-box ?
✅ Correction
Avec content-box :
Avec border-box :
/* Solution CSS */
.boite {
width: 300px;
padding: 20px;
border: 3px solid #000;
margin: 15px;
background: #eef2ff;
box-sizing: border-box; /* ou content-box pour tester */
}
Exercice 2 — Flexbox
Créez une barre de navigation avec Flexbox qui contient :
- Un logo à gauche
- 4 liens de navigation centrés
- Un bouton "Connexion" à droite
La barre doit avoir un fond sombre (#1a1a2e) et les liens doivent être blancs.
✅ Correction
<nav class="navbar-exo">
<div class="logo">MonLogo</div>
<ul class="menu-exo">
<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>
<a href="#" class="btn-connexion-exo">Connexion</a>
</nav>
.navbar-exo {
display: flex;
justify-content: space-between;
align-items: center;
background: #1a1a2e;
padding: 16px 30px;
color: white;
}
.logo {
font-size: 22px;
font-weight: 700;
}
.menu-exo {
display: flex;
list-style: none;
gap: 30px;
}
.menu-exo a {
color: white;
text-decoration: none;
}
.btn-connexion-exo {
color: white;
text-decoration: none;
padding: 8px 20px;
border: 1px solid rgba(255,255,255,0.3);
border-radius: 50px;
}
Exercice 3 — CSS Grid
Créez une grille de 6 éléments avec les spécifications suivantes :
- 3 colonnes de largeur égale
- Un espace de 15px entre les éléments
- L'élément 1 occupe 2 colonnes
- L'élément 4 occupe 2 lignes
✅ Correction
.grille-exo {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
}
.item-1 {
grid-column: span 2;
background: #e74c3c;
}
.item-4 {
grid-row: span 2;
background: #2ecc71;
}
/* Les autres éléments ont une couleur par défaut */
.item {
background: #4361ee;
color: white;
padding: 40px 20px;
text-align: center;
border-radius: 8px;
}
Exercice 4 — Responsive
À partir de l'exercice 3, rendez la grille responsive :
- Sur mobile (moins de 768px) : 1 colonne
- Sur tablette (768px - 1024px) : 2 colonnes
- Sur desktop (plus de 1024px) : 3 colonnes
✅ Correction
/* Version mobile (par défaut) */
.grille-exo {
display: grid;
grid-template-columns: 1fr;
gap: 15px;
}
/* Tablette */
@media (min-width: 768px) {
.grille-exo {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktop */
@media (min-width: 1024px) {
.grille-exo {
grid-template-columns: repeat(3, 1fr);
}
}
Exercice 5 — Animation
Créez une animation qui fait pivoter un élément de 360° et qui change de couleur du bleu au rouge en 2 secondes, en boucle infinie.
✅ Correction
@keyframes spinColor {
0% {
transform: rotate(0deg);
background: #4361ee;
}
100% {
transform: rotate(360deg);
background: #e74c3c;
}
}
.element-anime {
width: 100px;
height: 100px;
border-radius: 50%;
animation: spinColor 2s linear infinite;
}
- JavaScript
- SASS/LESS
- Tailwind CSS
- React / Vue
— Cours HTML & CSS