Positionnement CSS : static, relative, absolute, fixed
Introduction
Bienvenue dans ce cours sur le positionnement CSS, un concept fondamental pour maîtriser la mise en page de vos sites web. Comprendre comment positionner les éléments est crucial pour aller au-delà du simple agencement par défaut et créer des designs complexes et réactifs.
Par défaut, les éléments HTML s'afficment selon le flux normal du document. Cela signifie qu'ils se placent l'un après l'autre, de gauche à droite pour les éléments en ligne et de haut en bas pour les éléments de bloc, comme si vous lisiez un texte. Cependant, ce flux ne suffit pas toujours. Que faire si vous voulez superposer des éléments, fixer une barre de navigation en haut de l'écran, ou placer un badge dans le coin d'une image ? C'est là que la propriété CSS position entre en jeu.
La propriété position vous permet de manipuler la façon dont un élément est placé sur la page. Elle peut prendre plusieurs valeurs, chacune ayant un comportement distinct et des implications sur le flux du document :
staticrelativeabsolutefixed- (Il existe aussi
sticky, mais nous nous concentrerons sur les quatre principales pour cette introduction.)
Pour chaque valeur de position (sauf static), vous pouvez utiliser les propriétés top, right, bottom, et left pour décaler l'élément par rapport à son point de référence. La propriété z-index permet quant à elle de gérer la superposition des éléments.
Plongeons dans les détails de chaque valeur.
Comprendre la Propriété position
1. position: static;
static est la valeur par défaut de tous les éléments HTML. Lorsque vous ne spécifiez aucune propriété position pour un élément, il se comporte comme static.
- Comportement : L'élément est positionné selon le flux normal du document. Il se place naturellement après les éléments qui le précèdent et avant ceux qui le suivent.
- Déplacement : Les propriétés
top,right,bottom, etleftn'ont aucun effet sur un élément avecposition: static;. - Superposition : La propriété
z-indexn'a aucun effet sur un élément avecposition: static;. - Utilisation : C'est le comportement le plus courant pour la majorité des éléments de votre page. Vous n'avez généralement pas besoin de le déclarer explicitement, sauf si vous voulez "réinitialiser" un élément qui aurait hérité d'une autre valeur de
position.
Exemple simple :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Position Statique</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.boite {
width: 100px;
height: 100px;
background-color: lightblue;
border: 2px solid steelblue;
margin-bottom: 10px;
text-align: center;
line-height: 100px;
color: steelblue;
}
.boite-static {
/* position: static; est la valeur par défaut, donc pas nécessaire de la déclarer */
background-color: lightgreen;
border-color: darkgreen;
color: darkgreen;
}
</style>
</head>
<body>
<h1>Exemple de `position: static;`</h1>
<div class="boite">Boîte 1 (Défaut)</div>
<div class="boite boite-static">Boîte 2 (Static Explicit)</div>
<div class="boite">Boîte 3 (Défaut)</div>
</body>
</html>
Explication du code :
Dans cet exemple, les trois boîtes s'affichent les unes après les autres, de haut en bas, car elles sont toutes des éléments de bloc avec la propriété position: static; (implicitement ou explicitement). Tenter d'appliquer top ou left à .boite-static n'aurait aucun effet visible.
2. position: relative;
relative permet de décaler un élément par rapport à sa position normale dans le flux du document, sans affecter les éléments qui l'entourent.
- Comportement : L'élément est positionné selon le flux normal du document, mais ensuite il est décalé par rapport à sa position d'origine.
- Déplacement : Les propriétés
top,right,bottom, etleftpeuvent être utilisées pour décaler l'élément par rapport à sa position initiale.top: 20px;déplace l'élément de 20px vers le bas par rapport à sa position initiale.left: 30px;déplace l'élément de 30px vers la droite par rapport à sa position initiale.
- Espace réservé : L'élément
relativecontinue d'occuper l'espace dans le flux du document à sa position d'origine. C'est comme si une "ombre" de l'élément restait à sa place, et les autres éléments du document se positionnent en fonction de cette "ombre". - Superposition : La propriété
z-indexpeut être utilisée pour contrôler l'ordre de superposition des élémentsrelative(etabsolute,fixed,sticky). - Utilisation courante :
- Décaler légèrement un élément sans perturber le reste de la page.
- Conteneur pour les éléments
position: absolute;(c'est son rôle le plus important et le plus fréquent).
Exemple :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Position Relative</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.conteneur {
border: 2px dashed #ccc;
padding: 10px;
margin-bottom: 20px;
}
.boite {
width: 100px;
height: 100px;
background-color: lightblue;
border: 2px solid steelblue;
margin-bottom: 10px; /* Pour les boîtes statiques */
text-align: center;
line-height: 100px;
color: steelblue;
display: inline-block; /* Pour les aligner côte à côte */
vertical-align: top; /* Pour aligner en haut */
}
.boite-relative {
position: relative;
top: 20px; /* Déplace la boîte de 20px vers le bas */
left: 30px; /* Déplace la boîte de 30px vers la droite */
background-color: #ffcc99; /* Orange clair */
border-color: #cc6600; /* Orange foncé */
color: #cc6600;
}
</style>
</head>
<body>
<h1>Exemple de `position: relative;`</h1>
<div class="conteneur">
<h2>Boîtes positionnées :</h2>
<div class="boite">Boîte A (Défaut)</div>
<div class="boite boite-relative">Boîte B (Relative)</div>
<div class="boite">Boîte C (Défaut)</div>
</div>
</body>
</html>
Explication du code : La "Boîte B (Relative)" est décalée de 20px vers le bas et 30px vers la droite. Vous remarquerez que l'espace qu'elle occupait initialement est toujours "réservé" dans le flux du document. C'est pourquoi la "Boîte C (Défaut)" se place comme si la Boîte B n'avait pas bougé, ce qui peut créer un chevauchement avec la Boîte B si elle est déplacée.
3. position: absolute;
absolute est l'une des valeurs les plus puissantes et souvent source de confusion. Un élément absolute est retiré du flux normal du document.
- Comportement : L'élément
absoluteest sorti du flux. Les autres éléments se comportent comme s'il n'existait pas à sa position d'origine. - Déplacement : Les propriétés
top,right,bottom, etleftsont utilisées pour positionner l'élément. Mais la grande question est : par rapport à quoi ?- Un élément
absolutese positionne par rapport à son plus proche ancêtre positionné (c'est-à-dire un ancêtre qui n'a pasposition: static;). Cet ancêtre peut êtrerelative,absolute,fixed, ousticky. - Si aucun ancêtre positionné n'est trouvé, l'élément
absolutese positionne par rapport au bloc de conteneur initial (généralement l'élément<html>ou<body>).
- Un élément
- Espace réservé : L'élément
absolutene réserve plus d'espace dans le flux du document. C'est comme s'il était posé sur une couche distincte, flottant au-dessus ou en dessous du contenu normal. - Superposition : La propriété
z-indexa un effet complet et est souvent utilisée avecposition: absolute;. - Utilisation courante :
- Créer des pop-ups, des infobulles (tooltips), des menus déroulants.
- Placer des icônes ou des badges à des emplacements précis (par exemple, un badge "Nouveau" dans le coin d'une carte produit).
- Superposer des éléments.
Exemple : absolute à l'intérieur d'un conteneur relative
C'est le cas d'utilisation le plus courant et le plus recommandé pour absolute.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Position Absolute</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
height: 1000px; /* Pour avoir de quoi scroller */
}
.boite-conteneur {
position: relative; /* TRÈS IMPORTANT : ceci est l'ancêtre positionné */
width: 300px;
height: 200px;
background-color: #f0f8ff; /* Bleu très clair */
border: 2px dashed lightgray;
margin: 50px auto; /* Centrer le conteneur */
padding: 20px;
text-align: center;
line-height: 200px;
}
.boite-absolue {
position: absolute;
width: 80px;
height: 80px;
background-color: #ff6666; /* Rouge */
border: 2px solid darkred;
color: white;
text-align: center;
line-height: 80px;
font-weight: bold;
font-size: 0.9em;
/* Positionnement par rapport au conteneur relatif */
top: 10px;
right: 10px;
}
.texte-normal {
margin-top: 30px;
padding: 15px;
background-color: #f2f2f2;
border: 1px solid #ddd;
}
</style>
</head>
<body>
<h1>Exemple de `position: absolute;`</h1>
<div class="boite-conteneur">
Conteneur (position: relative;)
<div class="boite-absolue">Badge</div>
</div>
<p class="texte-normal">
Ce paragraphe est en dehors du conteneur. Notez que le "Badge" est positionné
par rapport au conteneur `relative`, et que le conteneur (et ce paragraphe)
ne sont pas affectés par la taille ou la position du badge, car le badge est sorti
du flux normal.
</p>
<div style="height: 500px; background-color: #eee; margin-top: 50px; text-align: center; padding-top: 200px;">
Contenu pour simuler un défilement
</div>
</body>
</html>
Explication du code :
Le div.boite-conteneur est défini avec position: relative;. Cela en fait le point de référence pour tous ses enfants ayant position: absolute;. Le div.boite-absolue est positionné avec top: 10px; et right: 10px; par rapport au bord supérieur-droit de son parent boite-conteneur. Le badge flotte au-dessus du conteneur et ne perturbe pas le flux des autres éléments.
4. position: fixed;
Les éléments fixed sont, comme absolute, retirés du flux normal du document. La différence majeure est leur point de référence.
- Comportement : L'élément
fixedest retiré du flux. Il est positionné par rapport au viewport (la fenêtre visible du navigateur). - Déplacement : Les propriétés
top,right,bottom, etleftsont utilisées pour positionner l'élément par rapport aux bords du viewport. - Défilement : Un élément
fixedreste à la même position dans le viewport, même lorsque l'utilisateur fait défiler la page. Il "colle" à l'écran. - Espace réservé : L'élément
fixedne réserve pas d'espace dans le flux du document. - Superposition : La propriété
z-indexa un effet complet et est couramment utilisée pour s'assurer que les éléments fixes apparaissent au-dessus du contenu de la page. - Utilisation courante :
- Barres de navigation (headers) qui restent visibles en haut de page.
- Boutons "Retour en haut" (scroll-to-top).
- Menus latéraux persistants.
- Barres de pied de page (footers) toujours visibles.
Exemple :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Position Fixed</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0; /* Important pour les éléments fixes */
padding-top: 60px; /* Pour laisser de l'espace au header fixe */
padding-bottom: 60px; /* Pour laisser de l'espace au footer fixe */
}
.header-fixe {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;
background-color: #333;
color: white;
text-align: center;
line-height: 50px;
z-index: 1000; /* Assure qu'il est au-dessus du contenu */
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
.footer-fixe {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50px;
background-color: #333;
color: white;
text-align: center;
line-height: 50px;
z-index: 1000; /* Assure qu'il est au-dessus du contenu */
box-shadow: 0 -2px 5px rgba(0,0,0,0.2);
}
.contenu-principal {
padding: 20px;
max-width: 800px;
margin: 20px auto;
line-height: 1.6;
}
.section-longue {
height: 400px;
background-color: #f9f9f9;
border: 1px dashed #ddd;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2em;
color: #666;
}
</style>
</head>
<body>
<div class="header-fixe">Ma Super Barre de Navigation Fixe</div>
<div class="contenu-principal">
<h1>Bienvenue sur notre page de démonstration</h1>
<p>
Ce texte est le contenu principal de la page.
Faites défiler vers le bas pour voir comment les barres de navigation fixes restent en place.
</p>
<div class="section-longue">
Section 1 : Contenu qui défile
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<div class="section-longue">
Section 2 : Contenu qui défile
</div>
<p>
Curabitur pretium tincidunt lacus. Nulla facilisi. In hac habitasse platea dictumst.
Etiam faucibus cursus urna. Ut eu risus. Duis imperdiet est non nunc.
Nulla est. Suspendisse eu lectus pellentesque, aliquet enim non, interdum urna.
Aliquam erat volutpat. Praesent congue erat at massa. Aenean in magna et lorem egestas fermentum.
</p>
<div class="section-longue">
Section 3 : Contenu qui défile
</div>
<p>
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Nulla facilisi. Integer lacinia sollicitudin massa. Cras in purus eu tellus ornare pharetra.
Donec a scelerisque dui. Nullam ac convallis lorem. Maecenas ut arcu lacus.
Mauris vel turpis et massa fermentum sollicitudin vel eu arcu.
Pellentesque eget nulla et ipsum consectetur varius. Nulla semper ipsum id nibh.
</p>
</div>
<div class="footer-fixe">Pied de page fixe - © 2023</div>
</body>
</html>
Explication du code :
Le div.header-fixe est positionné avec top: 0; et left: 0;, le plaçant en haut à gauche du viewport. Le div.footer-fixe est positionné avec bottom: 0; et left: 0;, le plaçant en bas à gauche du viewport. Lorsque vous faites défiler la page, ces deux éléments restent scotchés aux bords de la fenêtre du navigateur, offrant une expérience utilisateur cohérente. Notez l'utilisation de padding-top et padding-bottom sur le body pour empêcher le contenu de passer derrière les éléments fixes.
Concepts Associés
Le z-index
Lorsqu'on utilise les valeurs relative, absolute, fixed (et sticky), les éléments sont sortis du flux normal du document et peuvent se superposer. La propriété z-index permet de contrôler cet ordre de superposition.
- Fonctionnement :
z-indexaccepte des nombres entiers (positifs, négatifs ou zéro). Un élément avec unz-indexplus élevé apparaîtra au-dessus des éléments avec unz-indexplus faible. - Contexte d'empilement (Stacking Context) :
z-indexne fonctionne que sur les éléments qui ont une propriétépositionautre questatic. De plus,z-indexfonctionne au sein de "contextes d'empilement". Un nouvel ancêtre positionné (relative,absolute,fixed,sticky) crée un nouveau contexte d'empilement. Lesz-indexd'éléments enfants sont relatifs à leur propre contexte d'empilement, et non nécessairement à tous les autres éléments de la page. - Valeur par défaut : La valeur par défaut de
z-indexestauto, ce qui signifie que l'élément hérite de laz-indexde son parent, ou se comporte comme siz-index: 0;était appliqué.
Exemple de z-index :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Z-index</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.conteneur-zindex {
position: relative;
width: 300px;
height: 200px;
border: 2px solid #ccc;
background-color: #f0f0f0;
margin: 50px;
}
.boite-superposee {
position: absolute;
width: 150px;
height: 150px;
text-align: center;
line-height: 150px;
font-weight: bold;
font-size: 1.2em;
color: white;
}
.boite-rouge {
background-color: #e74c3c; /* Rouge */
top: 20px;
left: 20px;
z-index: 1; /* Sera derrière la bleue si la bleue a un z-index plus grand */
}
.boite-bleue {
background-color: #3498db; /* Bleu */
top: 60px;
left: 60px;
z-index: 2; /* Sera au-dessus de la rouge */
}
</style>
</head>
<body>
<h1>Utilisation de `z-index`</h1>
<div class="conteneur-zindex">
<div class="boite-superposee boite-rouge">Boîte Rouge (z-index: 1)</div>
<div class="boite-superposee boite-bleue">Boîte Bleue (z-index: 2)</div>
</div>
</body>
</html>
Explication du code :
Bien que la "Boîte Rouge" soit déclarée en premier dans le HTML (et devrait donc s'afficher par-dessus la "Boîte Bleue" par défaut si elles étaient au même niveau d'empilement et superposées), la "Boîte Bleue" a un z-index de 2, ce qui est supérieur à celui de la "Boîte Rouge" (1). Par conséquent, la "Boîte Bleue" apparaît au-dessus de la "Boîte Rouge".
Le Flux Normal du Document
Il est essentiel de bien comprendre ce qu'est le "flux normal du document" pour appréhender le positionnement CSS.
Le flux normal du document est l'ordre dans lequel les éléments sont affichés sur la page HTML par défaut, avant l'application de styles CSS qui modifieraient leur position.
- Éléments de bloc (
div,p,h1, etc.) : Occupent toute la largeur disponible et se placent les uns sous les autres. - Éléments en ligne (
span,a,img, etc.) : Occupent uniquement la largeur de leur contenu et se placent les uns à côté des autres sur la même ligne. S'il n'y a plus de place, ils passent à la ligne suivante.
Quand vous utilisez position: static;, l'élément reste dans ce flux. Quand vous utilisez position: relative;, l'élément reste dans ce flux conceptuellement (il y réserve toujours sa place), mais est visuellement décalé. Quand vous utilisez position: absolute; ou position: fixed;, l'élément est retiré du flux. C'est comme s'il était aspiré hors du document et placé sur une couche séparée, flottant au-dessus ou en dessous. Les autres éléments se comportent alors comme si l'élément retiré n'avait jamais été là.
Conclusion
Le positionnement CSS est une pierre angulaire de la conception web. En maîtrisant static, relative, absolute, et fixed, ainsi que z-index, vous serez capable de :
position: static;: Le comportement par défaut, les éléments suivent le flux normal du document. Les propriétés de décalage (top,left, etc.) etz-indexn'ont aucun effet.position: relative;: L'élément est décalé par rapport à sa position d'origine dans le flux. Il laisse un vide à sa place d'origine. Idéal pour décaler légèrement un élément ou, plus important encore, servir de point de référence pour les élémentsabsoluteenfants.position: absolute;: L'élément est retiré du flux normal du document. Il se positionne par rapport à son ancêtre positionné le plus proche, ou par rapport aubody/htmls'il n'y en a pas. Ne laisse pas de vide. Parfait pour les pop-ups, badges, etc.position: fixed;: L'élément est retiré du flux et positionné par rapport au viewport (la fenêtre du navigateur). Il reste en place même au défilement. Utile pour les barres de navigation persistantes.
N'oubliez pas que le positionnement peut être délicat au début. La clé est de pratiquer, d'expérimenter et d'utiliser l'inspecteur d'éléments de votre navigateur pour visualiser comment chaque propriété affecte le rendu de vos éléments. La compréhension du flux normal du document est la fondation sur laquelle toutes ces techniques de positionnement reposent.
Continuez à explorer et à coder !