Introduction au Développement HTML et CSS
Introduction au Développement HTML et CSS

Le système Grid CSS : Grille explicite et Zones nommées

Bienvenue à cette leçon dédiée au système Grid CSS, un module puissant et incontournable pour la création de mises en page bidimensionnelles sur le web. Dans le cadre de votre Introduction au Développement HTML et CSS, comprendre CSS Grid vous ouvrira de nouvelles perspectives pour des designs complexes, flexibles et responsives.

Nous allons explorer en détail comment créer une grille explicite en définissant directement vos lignes et colonnes, puis nous verrons la magie des zones nommées qui simplifient la disposition de vos éléments et améliorent grandement la lisibilité de votre code CSS.

1. Introduction au Système Grid CSS

CSS Grid Layout, souvent simplement appelé "Grid", est un système de mise en page CSS qui permet aux développeurs de concevoir des interfaces utilisateur bidimensionnelles. Contrairement à Flexbox, qui est optimisé pour des dispositions unidimensionnelles (lignes ou colonnes), Grid excelle dans la création de grilles complexes, avec des éléments organisés à la fois en lignes et en colonnes.

Pourquoi utiliser CSS Grid ?

  • Contrôle précis : Définissez la taille et le positionnement exacts de vos éléments.
  • Mises en page complexes : Créez des designs sophistiqués avec facilité.
  • Flexibilité : Adaptez votre mise en page à différentes tailles d'écran de manière intuitive.
  • Lisibilité du code : Particulièrement avec les zones nommées, votre CSS devient plus descriptif.

2. Les Fondamentaux de CSS Grid

Pour utiliser CSS Grid, vous devez d'abord désigner un élément comme conteneur de grille. Ses enfants directs deviendront alors des items de grille.

2.1. Le Conteneur de Grille : display: grid

La première étape consiste à transformer un élément HTML en conteneur de grille à l'aide de la propriété display.

.conteneur-de-grille {
    display: grid; /* Transforme l'élément en conteneur de grille */
}

Une fois display: grid appliqué, tous les enfants directs de .conteneur-de-grille deviennent automatiquement des items de grille et peuvent être positionnés sur la grille que nous allons définir.

3. La Grille Explicite (Explicit Grid)

Une grille explicite est une grille dont les lignes et les colonnes sont définies manuellement par le développeur. C'est la méthode la plus directe pour construire votre structure de grille.

3.1. Définir les Colonnes avec grid-template-columns

La propriété grid-template-columns vous permet de définir le nombre et la taille de vos colonnes.

  • Syntaxe : grid-template-columns: <taille-colonne-1> <taille-colonne-2> ...;
  • Unités courantes :
    • px, em, rem, % : Unités absolues ou relatives.
    • fr (fraction) : Unité flexible qui représente une fraction de l'espace disponible dans le conteneur de grille. C'est l'une des forces de Grid.
    • auto : Permet à la colonne de prendre la taille de son contenu ou de l'espace restant.
    • minmax(min, max) : Définit une taille minimale et une taille maximale pour la colonne.
    • repeat(nombre, taille) : Répète un modèle de colonne un certain nombre de fois.

Exemples :

.conteneur-grille-explicite {
    display: grid;
    /* Trois colonnes : 200px, 1 fraction de l'espace restant, et 15% de la largeur du conteneur */
    grid-template-columns: 200px 1fr 15%;

    /* Trois colonnes de taille égale (chacune prend 1/3 de l'espace) */
    grid-template-columns: 1fr 1fr 1fr;

    /* Utilisation de repeat() : Crée 4 colonnes de 100px */
    grid-template-columns: repeat(4, 100px);

    /* Deux colonnes, la première fait au moins 100px mais pas plus de 200px, la seconde prend l'espace restant */
    grid-template-columns: minmax(100px, 200px) 1fr;
}

3.2. Définir les Lignes avec grid-template-rows

Similaire à grid-template-columns, grid-template-rows définit le nombre et la taille de vos lignes.

  • Syntaxe : grid-template-rows: <taille-ligne-1> <taille-ligne-2> ...;
  • Les mêmes unités (px, em, rem, fr, auto, minmax, repeat()) s'appliquent.

Exemple :

.conteneur-grille-explicite {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr; /* 3 colonnes égales */
    grid-template-rows: 100px auto 50px; /* Première ligne de 100px, deuxième auto, troisième de 50px */
}

3.3. Placer des Items sur la Grille Explicite

Une fois la grille définie, vous pouvez positionner vos items en spécifiant sur quelles lignes et colonnes ils doivent commencer et se terminer.

  • grid-column-start / grid-column-end : Définit les lignes de colonne de début et de fin.
  • grid-row-start / grid-row-end : Définit les lignes de ligne de début et de fin.
  • Raccourcis :
    • grid-column: <start> / <end>;
    • grid-row: <start> / <end>;
    • grid-area: <row-start> / <column-start> / <row-end> / <column-end>; (Ce raccourci est également utilisé pour les zones nommées, mais peut prendre des numéros de ligne)

Exemple de placement explicite :

<div class="conteneur">
    <div class="item item-1">Item 1</div>
    <div class="item item-2">Item 2</div>
    <div class="item item-3">Item 3</div>
</div>
.conteneur {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /* 3 colonnes égales */
    grid-template-rows: 100px 100px; /* 2 lignes de 100px */
    gap: 10px; /* Espacement entre les cellules */
    border: 2px solid lightblue;
    padding: 10px;
}

.item {
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    padding: 15px;
    text-align: center;
}

.item-1 {
    /* Commence à la ligne de colonne 1, se termine à la ligne de colonne 3 (span 2 colonnes) */
    grid-column: 1 / 3;
    /* Commence à la ligne de rangée 1, se termine à la ligne de rangée 2 (span 1 rangée) */
    grid-row: 1 / 2;
    background-color: lightcoral;
}

.item-2 {
    grid-column: 3 / 4; /* Commence à la ligne de colonne 3, se termine à la ligne 4 (span 1 colonne) */
    grid-row: 1 / 3; /* Commence à la ligne de rangée 1, se termine à la ligne 3 (span 2 rangées) */
    background-color: lightgreen;
}

.item-3 {
    grid-column: 1 / 3; /* Commence à la ligne de colonne 1, se termine à la ligne 3 (span 2 colonnes) */
    grid-row: 2 / 3; /* Commence à la ligne de rangée 2, se termine à la ligne 3 (span 1 rangée) */
    background-color: lightgoldenrodyellow;
}

Dans cet exemple, l'item-1 s'étend sur 2 colonnes et 1 ligne. L'item-2 s'étend sur 1 colonne et 2 lignes. L'item-3 s'étend sur 2 colonnes et 1 ligne. Le placement par numéros de ligne peut devenir fastidieux pour des mises en page complexes, d'où l'intérêt des zones nommées.

4. Les Zones Nommées (Named Areas)

Les zones nommées sont une fonctionnalité incroyablement puissante de CSS Grid qui permet de nommer des sections de votre grille et de placer vos items en les référant par ces noms. Cela rend le code CSS plus sémantique, plus lisible et beaucoup plus facile à modifier.

4.1. Définir les Zones avec grid-template-areas

La propriété grid-template-areas est utilisée sur le conteneur de grille pour définir visuellement la structure de votre layout. Chaque chaîne de caractères représente une ligne de la grille, et les noms à l'intérieur de la chaîne représentent les colonnes.

  • Syntaxe : grid-template-areas: "nom-zone-1 nom-zone-2" "nom-zone-3 ." ...;
  • Chaque chaîne doit avoir le même nombre de "cellules" que le nombre de colonnes définies par grid-template-columns.
  • Un point (.) représente une cellule vide.
  • Si vous nommez une zone, elle occupera toutes les cellules consécutives portant ce même nom.

Exemple conceptuel :

Imaginez une mise en page classique avec un en-tête, une navigation, un contenu principal, une barre latérale et un pied de page.

.layout-container {
    display: grid;
    grid-template-columns: 1fr 3fr 1fr; /* Trois colonnes: nav/aside, main, aside/nav */
    grid-template-rows: auto 1fr auto; /* Trois lignes: header, content, footer */
    grid-template-areas:
        "header  header  header"  /* L'en-tête s'étend sur toutes les 3 colonnes */
        "nav     main    aside"   /* La navigation, le contenu principal et la barre latérale */
        "footer  footer  footer"; /* Le pied de page s'étend sur toutes les 3 colonnes */
    gap: 10px;
}

Ce code CSS dessine mentalement la grille suivante :

| header | header | header | | :----: | :----: | :----: | | nav | main | aside | | footer | footer | footer |

4.2. Attacher les Items aux Zones avec grid-area

Une fois les zones définies sur le conteneur, vous attribuez chaque item de grille à une zone nommée en utilisant la propriété grid-area sur l'item lui-même.

  • Syntaxe : grid-area: <nom-de-la-zone>;

Exemple complet de zones nommées :

Reprenons notre structure HTML classique et appliquons les zones nommées.

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemple CSS Grid : Zones Nommées</title>
    <style>
        body {
            font-family: sans-serif;
            margin: 20px;
            background-color: #f4f4f4;
        }

        .grid-container {
            display: grid;
            grid-template-columns: 200px 1fr 250px; /* Col.1: Nav, Col.2: Main, Col.3: Aside */
            grid-template-rows: auto 1fr auto; /* Ligne 1: Header, Ligne 2: Content, Ligne 3: Footer */
            gap: 20px; /* Espacement entre les items de grille */
            min-height: 80vh; /* Pour visualiser l'étirement du contenu */
            border: 2px solid #333;
            padding: 20px;
            background-color: white;

            /* Définition des zones nommées */
            grid-template-areas:
                "header header header" /* L'en-tête occupe les 3 colonnes de la première ligne */
                "nav    main   aside"  /* Nav, Main, Aside sur la deuxième ligne */
                "footer footer footer"; /* Le pied de page occupe les 3 colonnes de la dernière ligne */
        }

        /* Styles généraux pour les items */
        .grid-item {
            background-color: #e0e0e0;
            border: 1px solid #bbb;
            padding: 20px;
            text-align: center;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            color: #333;
        }

        /* Attribution des items aux zones nommées */
        .header {
            grid-area: header; /* Cet item sera placé dans la zone 'header' */
            background-color: #007bff;
            color: white;
            font-size: 1.5em;
        }

        .nav {
            grid-area: nav; /* Cet item sera placé dans la zone 'nav' */
            background-color: #28a745;
            color: white;
        }

        .main-content {
            grid-area: main; /* Cet item sera placé dans la zone 'main' */
            background-color: #ffc107;
            color: #333;
            text-align: left;
            display: block; /* Supprimer flex pour laisser le contenu s'écouler */
        }

        .main-content p {
            margin-bottom: 10px;
            line-height: 1.6;
        }

        .aside {
            grid-area: aside; /* Cet item sera placé dans la zone 'aside' */
            background-color: #dc3545;
            color: white;
        }

        .footer {
            grid-area: footer; /* Cet item sera placé dans la zone 'footer' */
            background-color: #6c757d;
            color: white;
        }

        /* Media Queries pour le Responsive Design */
        @media (max-width: 768px) {
            .grid-container {
                /* Sur petits écrans, empilez les éléments verticaux */
                grid-template-columns: 1fr; /* Une seule colonne */
                grid-template-rows: auto auto 1fr auto auto; /* Header, Nav, Main, Aside, Footer */
                grid-template-areas:
                    "header"
                    "nav"
                    "main"
                    "aside"
                    "footer";
            }
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <header class="grid-item header">En-tête du Site</header>
        <nav class="grid-item nav">Navigation Principale</nav>
        <main class="grid-item main-content">
            <h2>Contenu Principal</h2>
            <p>
                Ceci est le contenu principal de la page. Il s'étend sur la zone nommée 'main'. 
                Grâce à CSS Grid et aux zones nommées, organiser des mises en page complexes devient 
                incroyablement intuitif et lisible. Imaginez la flexibilité pour différentes tailles d'écran !
            </p>
            <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.
            </p>
        </main>
        <aside class="grid-item aside">Barre Latérale</aside>
        <footer class="grid-item footer">Pied de Page &copy; 2023</footer>
    </div>
</body>
</html>

Explication du code :

  1. grid-container:

    • display: grid;: L'élément div devient un conteneur de grille.
    • grid-template-columns: 200px 1fr 250px;: Nous définissons trois colonnes. La première fait 200px de large (pour la navigation), la troisième 250px (pour l'aside), et la colonne du milieu (main) prend toute la largeur restante grâce à 1fr.
    • grid-template-rows: auto 1fr auto;: Nous définissons trois lignes. La première et la dernière (header, footer) s'adaptent à leur contenu (auto), tandis que la ligne du milieu (main, nav, aside) prend le reste de l'espace vertical disponible (1fr).
    • grid-template-areas: ...;: C'est ici que la magie opère. Nous dessinons notre mise en page visuellement. Chaque chaîne entre guillemets est une ligne.
      • "header header header": La zone 'header' s'étend sur les trois colonnes de la première ligne.
      • "nav main aside": Sur la deuxième ligne, nous avons les zones 'nav', 'main' et 'aside', chacune dans sa colonne respective.
      • "footer footer footer": La zone 'footer' s'étend sur les trois colonnes de la troisième ligne.
    • gap: 20px;: Ajoute un espacement de 20px entre les cellules de la grille.
  2. grid-item (et ses variations):

    • Chaque élément enfant du conteneur (<header>, <nav>, <main>, <aside>, <footer>) est un item de grille.
    • La propriété grid-area: <nom-de-la-zone>; est appliquée à chaque item pour l'assigner à la zone nommée correspondante définie dans grid-template-areas. Par exemple, .header { grid-area: header; } place l'élément <header> dans la zone que nous avons appelée "header".
  3. @media (max-width: 768px):

    • Démontre la facilité de créer un responsive design avec les zones nommées. Pour les écrans plus petits, nous modifions simplement grid-template-columns pour avoir une seule colonne et réorganisons grid-template-areas pour que les éléments s'empilent verticalement. Le HTML ne change pas, seule la disposition CSS est modifiée.

5. Bonnes Pratiques et Conseils

  • Grid vs Flexbox :

    • Grid est pour les mises en page bidimensionnelles (lignes et colonnes simultanément).
    • Flexbox est pour les composants unidimensionnels (une ligne ou une colonne).
    • Ils ne sont pas mutuellement exclusifs ! Vous pouvez avoir un conteneur Grid, et à l'intérieur de l'un de ses items, utiliser Flexbox pour organiser son contenu.
  • gap (anciennement grid-gap) : Utilisez la propriété gap sur le conteneur de grille pour ajouter de l'espace entre les cellules. Vous pouvez spécifier row-gap et column-gap séparément ou utiliser le raccourci gap: <row-gap> <column-gap>; ou simplement gap: <all-gaps>;.

  • Nommez vos lignes et colonnes (Avancé) : Bien que les zones nommées soient les plus courantes, vous pouvez également nommer les lignes et colonnes de votre grille explicitement avec grid-template-columns: [col-start] 1fr [col-end]...; et placer les items en utilisant ces noms, par exemple grid-column: col-start / col-end;.

  • Inspecteur de navigateur : Les outils de développement des navigateurs modernes (Chrome, Firefox) offrent des outils excellents pour visualiser et déboguer les grilles CSS. Activez l'affichage de la grille pour voir les lignes, les numéros et les noms des zones.

6. Conclusion et Résumé

Le système Grid CSS est une révolution pour la conception de mises en page web. Il offre un contrôle sans précédent sur la disposition bidimensionnelle de vos éléments.

Nous avons couvert :

  • La déclaration d'un conteneur de grille avec display: grid.
  • La création d'une grille explicite en définissant directement les tailles des colonnes (grid-template-columns) et des lignes (grid-template-rows).
  • Le placement des items sur cette grille explicite à l'aide de numéros de ligne (grid-column, grid-row).
  • La puissance des zones nommées avec grid-template-areas sur le conteneur pour une définition visuelle et sémantique de la mise en page.
  • L'attribution des items à ces zones nommées avec grid-area sur les items.

En maîtrisant ces concepts, vous êtes désormais armés pour créer des mises en page web complexes, maintenables et responsives avec une élégance et une efficacité que les méthodes traditionnelles ne pouvaient égaler. Continuez à expérimenter et à construire !