Tout expliqué avec des exemples visuels
Formation DWWM - 2025-2026
On va comprendre le positionnement CSS :
Comprendre avant de coder
👆 Ils se placent automatiquement les uns à côté des autres
position !| Valeur | Comportement | Usage |
|---|---|---|
| static | Par défaut, flux normal | 95% des éléments |
| relative | Décalé par rapport à soi | Légers ajustements |
| absolute | Sorti du flux, positionné | Pop-ups, badges |
| fixed | Collé à l'écran | Navbar, bouton flottant |
| sticky | Normal puis collé | En-têtes de tableau |
top : Distance du hautright : Distance de la droitebottom : Distance du basleft : Distance de la gaucheposition !position, top et left ne font rien !
La position par défaut
/* Ces deux codes sont IDENTIQUES */
/* Version 1 : sans rien (static par défaut) */
.box {
background: blue;
padding: 20px;
}
/* Version 2 : avec position static (pareil !) */
.box {
background: blue;
padding: 20px;
position: static; /* Inutile, c'est déjà le défaut */
}
position: static/* ❌ Ceci NE MARCHE PAS */
.box {
position: static;
top: 50px; /* IGNORÉ ! */
left: 100px; /* IGNORÉ ! */
}
/* La boîte reste dans le flux normal
top et left sont complètement ignorés */
top, right, bottom, leftposition: relative/absolute/fixed/sticky
Flux normal (static) :
👆 Les 3 boîtes se suivent naturellement
Se décaler par rapport à soi-même
.box {
position: relative;
top: 20px; /* Descend de 20px */
left: 30px; /* Va à droite de 30px */
}
/* L'élément se déplace de 20px vers le BAS
et de 30px vers la DROITE
PAR RAPPORT à sa position d'origine */
top: 20px → "Pousse-moi de 20px DEPUIS le haut" = Descendleft: 30px → "Pousse-moi de 30px DEPUIS la gauche" = Va à droitebottom: 20px → "Pousse-moi de 20px DEPUIS le bas" = Monteright: 30px → "Pousse-moi de 30px DEPUIS la droite" = Va à gauche
Avec position: relative :
👆 Box 2 est décalée mais son espace reste réservé !
Box 3 ne remonte pas pour combler le vide
absolute !
<div class="carte" style="position: relative;">
<img src="produit.jpg">
<span class="badge" style="position: absolute; top: 10px; right: 10px;">
NOUVEAU
</span>
</div>
/* Le parent est relative */
.carte {
position: relative; /* Devient la référence ! */
}
/* L'enfant est absolute */
.badge {
position: absolute;
top: 10px; /* 10px du HAUT de .carte */
right: 10px; /* 10px de la DROITE de .carte */
}
:hover)/* Exemple : bouton qui monte au survol */
.btn {
position: relative;
transition: top 0.3s;
}
.btn:hover {
top: -3px; /* Monte de 3px */
}
Sortir complètement du flux
Avec absolute :
👆 Box 2 est SORTIE du flux !
Box 3 remonte comme si Box 2 n'existait pas
absolute se positionne par rapport à son premier parent positionnéposition: relative/absolute/fixed)
<div class="parent" style="position: relative; width: 300px; height: 200px;">
<div class="enfant" style="position: absolute; top: 20px; right: 20px;">
Badge
</div>
</div>
/* Le parent DOIT être positionné */
.parent {
position: relative; /* Devient la référence */
width: 300px;
height: 200px;
}
/* L'enfant est absolute */
.enfant {
position: absolute;
top: 20px; /* 20px du HAUT du parent */
right: 20px; /* 20px de la DROITE du parent */
}
position: relative/absolute/fixed
👆 Les enfants absolute flottent dans le parent relative
<body>
<body>
<div> <!-- position: static -->
<div> <!-- position: static -->
<span style="position: absolute; top: 0; right: 0;">
Badge
</span>
</div>
</div>
</body>
<!-- Le badge sera en HAUT à DROITE de TOUTE la page ! -->
position: relative sur le parent !/* Technique pour centrer parfaitement */
.modal {
position: absolute;
top: 50%; /* Milieu vertical */
left: 50%; /* Milieu horizontal */
transform: translate(-50%, -50%); /* Recentrer */
width: 400px;
height: 300px;
}
/* OU avec les 4 directions (pour remplir) */
.overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* Remplit TOUT le parent */
}
/* Exemple : Badge "Nouveau" sur image */
.product-card {
position: relative; /* Parent = référence */
}
.badge-nouveau {
position: absolute;
top: 10px;
right: 10px;
background: red;
color: white;
padding: 5px 10px;
border-radius: 5px;
}
Coller à l'écran
| Critère | Absolute | Fixed |
|---|---|---|
| Par rapport à | Parent positionné | Écran (viewport) |
| Quand on scroll | Scroll avec la page | NE BOUGE PAS |
| Sorti du flux | ✅ Oui | ✅ Oui |
| Usage typique | Badges, tooltips | Navbar, bouton flottant |
/* Navbar qui reste en haut */
.navbar {
position: fixed;
top: 0; /* Collé en haut */
left: 0; /* Collé à gauche */
right: 0; /* Collé à droite (= largeur 100%) */
background: white;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
z-index: 1000; /* Au-dessus de tout */
}
/* Bouton "Retour en haut" en bas à droite */
.back-to-top {
position: fixed;
bottom: 20px; /* 20px du bas de l'écran */
right: 20px; /* 20px de la droite de l'écran */
background: blue;
color: white;
padding: 15px;
border-radius: 50%;
cursor: pointer;
}
/* ❌ PROBLÈME : Le titre est caché sous la navbar */
.navbar {
position: fixed;
top: 0;
height: 60px;
}
h1 {
/* Le h1 commence à 0px du haut
= Caché sous la navbar ! */
}
/* ✅ SOLUTION : Ajouter un padding au body */
body {
padding-top: 60px; /* Hauteur de la navbar */
}
/* Maintenant le contenu commence APRÈS la navbar */
Le meilleur des deux mondes
/* En-tête de tableau qui se colle */
thead {
position: sticky;
top: 0; /* Se colle à 0px du haut */
background: white; /* Important : cache le contenu qui passe dessous */
z-index: 10;
}
/* Menu de navigation sticky */
.menu {
position: sticky;
top: 80px; /* Se colle à 80px du haut (sous la navbar) */
}
/* Sidebar qui suit */
.sidebar {
position: sticky;
top: 20px;
max-height: calc(100vh - 40px); /* Hauteur max = écran - marges */
}
top ou bottom, sticky ne fonctionne pas !
top ou bottomoverflow: hidden/* ❌ NE MARCHE PAS */
.parent {
overflow: hidden; /* BLOQUE sticky ! */
}
.sticky {
position: sticky;
top: 0;
}
/* ✅ SOLUTION : Enlever overflow: hidden du parent */
.parent {
/* Pas d'overflow */
}
.sticky {
position: sticky;
top: 0; /* Maintenant ça marche ! */
}
<!-- Exemple : Titres de sections qui se collent -->
<section>
<h2 style="position: sticky; top: 0;">Section 1</h2>
<p>Contenu long...</p>
</section>
<section>
<h2 style="position: sticky; top: 0;">Section 2</h2>
<p>Contenu long...</p>
</section>
<!-- Quand vous scrollez, chaque h2 se colle puis est remplacé par le suivant ! -->
Qui passe devant/derrière ?
/* Navbar au-dessus de tout */
.navbar {
position: fixed;
top: 0;
z-index: 1000; /* Très haut = au-dessus */
}
/* Modal par-dessus la navbar */
.modal {
position: fixed;
z-index: 2000; /* Encore plus haut */
}
/* Overlay (fond sombre) entre navbar et modal */
.overlay {
position: fixed;
z-index: 1500; /* Entre les deux */
background: rgba(0,0,0,0.5);
}
z-index est ignoré si position: static
| Z-index | Élément | Usage |
|---|---|---|
| 1-10 | Éléments normaux | Tooltips, badges |
| 100 | Dropdowns | Menus déroulants |
| 1000 | Navbar, Header | Navigation fixe |
| 2000+ | Modals, Overlays | Pop-ups importantes |
| 9999 | Notifications | Au-dessus de TOUT |
/* Élément DERRIÈRE son parent */
.background-decoration {
position: absolute;
z-index: -1; /* DERRIÈRE */
/* Passe derrière le contenu du parent */
}
/* Exemple : fond décoratif derrière du texte */
.card {
position: relative;
}
.card::before {
content: '';
position: absolute;
z-index: -1;
background: linear-gradient(...);
/* Reste DERRIÈRE le texte de .card */
}
Quand utiliser quoi ?
| Position | Dans le flux ? | Par rapport à | Usage principal |
|---|---|---|---|
| static | ✅ Oui | Flux normal | 95% des éléments |
| relative | ✅ Oui (fantôme) | Soi-même | Parent de référence |
| absolute | ❌ Non | Parent positionné | Badges, tooltips |
| fixed | ❌ Non | Écran (viewport) | Navbar, bouton flottant |
| sticky | ✅ Oui puis colle | Parent + écran | En-têtes tableau |
<div class="product-card">
<span class="badge-promo">-20%</span>
<img src="produit.jpg" alt="Produit">
<h3>Nom du produit</h3>
<p class="price">29.99€</p>
</div>
/* Parent = relative (référence) */
.product-card {
position: relative;
border: 1px solid #ddd;
padding: 15px;
}
/* Badge = absolute (flotte sur l'image) */
.badge-promo {
position: absolute;
top: 10px;
right: 10px;
background: red;
color: white;
padding: 5px 10px;
border-radius: 5px;
z-index: 10;
}
<nav class="navbar">
<div class="logo">MonSite</div>
<ul class="menu">...</ul>
</nav>
<button class="back-to-top">↑</button>
/* Navbar = fixed (reste en haut) */
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
background: white;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
z-index: 1000;
}
/* Bouton = fixed (bas droite) */
.back-to-top {
position: fixed;
bottom: 30px;
right: 30px;
background: blue;
color: white;
width: 50px;
height: 50px;
border-radius: 50%;
z-index: 999;
}
<div class="modal-overlay"></div>
<div class="modal">
<button class="close">×</button>
<h2>Titre de la modal</h2>
<p>Contenu...</p>
</div>
/* Overlay = fixed (couvre tout l'écran) */
.modal-overlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0,0,0,0.7); /* Fond noir transparent */
z-index: 1000;
}
/* Modal = fixed (centrée) */
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
width: 500px;
padding: 30px;
border-radius: 10px;
z-index: 1001; /* Au-dessus de l'overlay */
}
/* Bouton fermer = absolute (dans la modal) */
.close {
position: absolute;
top: 10px;
right: 10px;
}
<table>
<thead>
<tr>
<th>Nom</th>
<th>Email</th>
<th>Téléphone</th>
</tr>
</thead>
<tbody>
<!-- 100 lignes de données... -->
</tbody>
</table>
/* Table normale */
table {
width: 100%;
border-collapse: collapse;
}
/* En-tête = sticky (se colle en scrollant) */
thead {
position: sticky;
top: 0;
background: #f5f5f5;
z-index: 10;
}
th {
padding: 15px;
text-align: left;
border-bottom: 2px solid #ddd;
}
/* ❌ L'absolute ne sait pas où se placer ! */
.parent {
/* Pas de position ! */
}
.enfant {
position: absolute; /* Va chercher un autre parent ! */
}
/* ❌ top/left sont ignorés ! */
.box {
/* position: static par défaut */
top: 20px; /* NE MARCHE PAS */
}
/* ❌ Sticky ne marche pas ! */
.menu {
position: sticky;
/* Manque top ou bottom ! */
}
Vous maîtrisez maintenant les positions CSS ! 🚀
📐 Pratiquez avec des exemples concrets !
La meilleure façon d'apprendre = expérimenter ! 💪