Séance 6 : Positionnement Relatif et Absolu - Contrôle Précis

1. Maîtriser le Positionnement CSS

1.1 Introduction au Positionnement CSS

Jusqu'à présent, nous avons principalement travaillé avec le flux normal du document, où les éléments s'affichent les uns après les autres (blocs verticaux, en ligne horizontaux). Avec Flexbox et CSS Grid, vous avez appris à organiser des groupes d'éléments. Cependant, il est parfois nécessaire de positionner un élément de manière très spécifique, en le décalant par rapport à sa position normale, ou même en le retirant complètement du flux. C'est là qu'intervient la propriété position en CSS.

Positionnement CSS

1.2 Positionnement Statique (static)

Le positionnement static est la valeur par défaut de tous les éléments HTML. Les éléments avec position: static; sont affichés dans l'ordre normal du document. Les propriétés de décalage (top, bottom, left, right) n'ont aucun effet sur eux.

.element-static {
    position: static; /* C'est la valeur par défaut, souvent non déclarée */
    top: 20px; /* N'aura aucun effet */
}

1.3 Positionnement Relatif (relative)

Un élément avec position: relative; est positionné par rapport à sa position normale dans le flux du document. Lorsque vous utilisez top, bottom, left, ou right, l'élément est décalé de cette position normale. Cependant, l'espace qu'il aurait occupé dans le flux reste réservé, ce qui signifie qu'il ne chevauche pas les autres éléments à moins d'être décalé suffisamment.

<div class="container">
    <div class="box">Boîte 1</div>
    <div class="box relative-box">Boîte Relative</div>
    <div class="box">Boîte 3</div>
</div>
.container {
    border: 2px dashed #A5B4FC;
    padding: 20px;
    display: flex;
}
.box {
    width: 80px;
    height: 80px;
    background-color: #BFDBFE;
    border: 1px solid #60A5FA;
    margin: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.relative-box {
    position: relative;
    top: 20px; /* Décalé de 20px vers le bas par rapport à sa position normale */
    left: 20px; /* Décalé de 20px vers la droite par rapport à sa position normale */
    background-color: #FCA5A5; /* lightcoral */
}

1.4 Positionnement Absolu (absolute)

Un élément avec position: absolute; est retiré du flux normal du document. Cela signifie qu'il n'occupe plus d'espace et que les autres éléments se comportent comme s'il n'existait pas. Il est positionné par rapport à son ancêtre positionné le plus proche (c'est-à-dire le parent, grand-parent, etc., qui a une position autre que static). S'il n'y a pas d'ancêtre positionné, il se positionne par rapport au corps du document (<body>).

Règle d'or : Pour positionner un élément absolument à l'intérieur d'un conteneur spécifique, assurez-vous que ce conteneur parent a une position: relative; (ou absolute, fixed, sticky).

<div class="parent-relative">
    Parent Relative
    <div class="absolute-box">Boîte Absolue</div>
</div>
<div class="sibling-box">Boîte Frère</div>
.parent-relative {
    position: relative; /* Le parent est positionné */
    width: 300px;
    height: 200px;
    border: 2px solid #4F46E5; /* indigo-600 */
    padding: 20px;
    margin-bottom: 20px;
    background-color: #EEF2FF; /* indigo-50 */
}
.absolute-box {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 100px;
    height: 100px;
    background-color: #FCA5A5; /* lightcoral */
    border: 1px solid #DC2626; /* red-600 */
    display: flex;
    justify-content: center;
    align-items: center;
}
.sibling-box {
    width: 150px;
    height: 50px;
    background-color: #BFDBFE;
    border: 1px solid #60A5FA;
    margin-top: 10px; /* La boîte absolue ne l'affecte plus */
}

1.5 Positionnement Fixe (fixed)

Un élément avec position: fixed; est positionné par rapport à la fenêtre d'affichage (viewport). Il est également retiré du flux normal du document. Un élément fixe reste au même endroit sur l'écran, même lorsque l'utilisateur fait défiler la page. C'est idéal pour les barres de navigation persistantes, les boutons "retour en haut" ou les pop-ups.

<div class="fixed-header">En-tête Fixe</div>
<div class="content-placeholder">
    <p>Contenu de la page... (faites défiler pour voir l'effet du fixe)</p>
    <!-- Répétez ce paragraphe plusieurs fois pour créer du défilement -->
</div>
.fixed-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    background-color: #4F46E5; /* indigo-600 */
    color: white;
    padding: 15px;
    text-align: center;
    z-index: 1000; /* Pour s'assurer qu'il est au-dessus du contenu */
}
.content-placeholder {
    margin-top: 60px; /* Pour éviter que le contenu ne soit caché par l'en-tête fixe */
    padding: 20px;
    height: 1200px; /* Pour forcer le défilement */
    background-color: #F8FAFC;
}

1.6 Positionnement Sticky (sticky)

Le positionnement sticky est un hybride entre relative et fixed. Un élément sticky se comporte comme un élément relatif jusqu'à ce qu'il atteigne un certain seuil de défilement (défini par top, bottom, left, ou right dans le viewport), après quoi il devient "fixe" à cette position. C'est parfait pour les en-têtes de section qui restent visibles lorsque vous faites défiler leur contenu.

<div class="scroll-container">
    <h3 class="sticky-header">Titre Sticky</h3>
    <p>Contenu qui défile...</p>
    <!-- Répétez ce paragraphe plusieurs fois -->
    <p>Plus de contenu...</p>
</div>
.scroll-container {
    height: 400px; /* Conteneur avec défilement */
    overflow-y: scroll;
    border: 2px solid #10B981; /* emerald-500 */
    padding: 10px;
}
.sticky-header {
    position: sticky;
    top: 0; /* Devient fixe à 0px du haut du conteneur parent en défilement */
    background-color: #D1FAE5; /* emerald-100 */
    padding: 10px;
    border-bottom: 1px solid #10B981;
    z-index: 10; /* Pour s'assurer qu'il est au-dessus du contenu */
}
.scroll-container p {
    margin-bottom: 15px;
    line-height: 1.6;
}

1.7 La Propriété z-index : Gérer les Calques

Lorsque des éléments se chevauchent en raison du positionnement, la propriété z-index permet de contrôler leur ordre d'empilement (qui apparaît au-dessus de qui). Une valeur de z-index plus élevée signifie que l'élément sera affiché au-dessus des éléments avec une valeur plus basse.

Important : z-index ne fonctionne que sur les éléments qui ont une position autre que static (c'est-à-dire relative, absolute, fixed, ou sticky).

<div class="z-container">
    <div class="z-box z-box-1">Z-index 1</div>
    <div class="z-box z-box-2">Z-index 2</div>
    <div class="z-box z-box-3">Z-index 3</div>
</div>
.z-container {
    position: relative;
    width: 300px;
    height: 200px;
    border: 2px dashed #A5B4FC;
    margin: 30px;
}
.z-box {
    position: absolute;
    width: 100px;
    height: 100px;
    border: 1px solid white;
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
}
.z-box-1 {
    background-color: #EF4444; /* red-500 */
    top: 10px;
    left: 10px;
    z-index: 1;
}
.z-box-2 {
    background-color: #F97316; /* orange-500 */
    top: 30px;
    left: 30px;
    z-index: 2;
}
.z-box-3 {
    background-color: #EAB308; /* yellow-500 */
    top: 50px;
    left: 50px;
    z-index: 3;
}

1.8 Interactivité en Pur CSS : La Pseudo-classe :target

Avant de passer aux exercices, découvrons une technique puissante pour simuler de l'interactivité sans utiliser de JavaScript. La pseudo-classe :target permet de styliser un élément lorsqu'il est la "cible" de l'URL, c'est-à-dire quand son id correspond au hash (#) dans l'URL.

Par exemple, si vous cliquez sur un lien <a href="#section2">, l'élément <div id="section2"> deviendra la cible, et les styles définis dans #section2:target { ... } lui seront appliqués. C'est parfait pour afficher ou masquer des éléments.

2. Exercices d'Application

Pour chaque exercice, créez un nouveau fichier HTML et CSS. N'oubliez pas d'utiliser les variables de notre Design System pour les couleurs, espacements et tailles de police.

Exercice 1 : Boîte Relative Décalée

Exercice 2 : Icône Absolue dans un Conteneur

Exercice 3 : Barre de Navigation Fixe

Exercice 4 : Section Sticky

3. TP : Création d'une Modale (Pop-up) en Pur CSS avec :target

Pour ce TP, vous allez utiliser la pseudo-classe :target pour créer une modale entièrement fonctionnelle qui apparaît et disparaît au-dessus du contenu, sans aucune ligne de JavaScript.

Objectif :

Concevoir une fenêtre modale qui s'ouvre en cliquant sur un lien et se ferme en cliquant sur un autre, en utilisant uniquement HTML et CSS.

Consignes :

  1. Créez un nouveau dossier tp-seance6-modal-css avec index.html et styles.css.
  2. Dans index.html :
    • Ajoutez un lien qui servira de bouton d'ouverture : <a href="#open-modal" class="button">Ouvrir la Modale</a>.
    • Créez la structure de la modale. Elle doit avoir un id correspondant au href du lien : <div id="open-modal" class="modal-overlay">...</div>.
    <!-- Le lien pour ouvrir -->
    <a href="#open-modal" class="bg-blue-500 text-white py-2 px-4 rounded">Ouvrir la Modale</a>
    
    <!-- La modale elle-même -->
    <div id="open-modal" class="modal-overlay">
        <div class="modal-content">
            <h2>Titre de la Modale</h2>
            <p>Ceci est une modale en pur CSS !</p>
            
            <!-- Le lien pour fermer (pointe vers un hash qui n'existe pas ou #) -->
            <a href="#" class="close-button">&times;</a>
        </div>
    </div>
  3. Dans votre styles.css :
    • .modal-overlay :
      • Stylez-le comme dans l'exercice précédent (position: fixed, couvrant tout l'écran, fond semi-transparent, z-index élevé).
      • Utilisez display: flex pour centrer le contenu.
      • La clé : Par défaut, il doit être masqué. Au lieu de display: none, nous utilisons visibility: hidden; et opacity: 0; pour permettre une transition.
    • .modal-overlay:target :
      • C'est ici que la magie opère. Quand la modale est ciblée, rendez-la visible : visibility: visible; et opacity: 1;.
      • Ajoutez une transition sur .modal-overlay pour que l'apparition soit douce.
    • .modal-content :
      • Stylez le contenu de la modale (fond blanc, padding, etc.) et donnez-lui une position: relative.
    • .close-button :
      • Positionnez-le en absolute dans le coin supérieur droit du .modal-content.
  4. Vérification : Ouvrez la page. La modale doit être cachée. Cliquez sur "Ouvrir la Modale". L'URL doit changer en ...#open-modal et la modale doit apparaître. Cliquez sur la croix. L'URL doit revenir à ...# et la modale doit disparaître.