CSS : En 2024 les Grids c'est has been ?

Jean-Noël - Jul 29 - - Dev Community

Introduction

Tout le monde sait ce qu'est un affichage responsive en 2024 : c'est occuper intelligemment l'espace disponible pour un affichage optimal en terme d'esthétique et d'ergonomie vis-à-vis des différents supports d'affichage (smartphone, tablette, ordinateur de bureau...).

Mais histoire de revenir aux fondamentaux, en full CSS comment fait-on du responsive design aujourd'hui ?

Pour ce faire, le CSS a mis à notre disposition ces principaux outils :

  • les grids (...et subgrids 😯) !
  • les flexboxs
  • et les media queries

En pratique, nombreux sont les développeurs à avoir complètement abandonné les grids (plutôt historiques, donc) au profit des flexboxs, qui paraissent très similaires tout en étant (un peu) plus modernes.

Mais alors : pourquoi les grids existent toujours ? Ne serait-on pas là, en présence d'un outil quelque peu dépassé ?

Dans l'optique de mieux situer les grids par rapport aux flexboxs, je vous propose de refaire un tour d'horizon de leurs fonctionnalités : comment, mais aussi quand se servir plutôt de l'un ou de l'autre. Et vous allez voir que les grids ont peut-être un peu plus à proposer que ce qu'on croyait !

Les Flexboxs

Comme vous le savez sans doute, la Flexbox propose un système d'alignement beaucoup plus flexible que son homologue Grid. Mais elle a la particularité de se concentrer avant tout sur 1 seul axe principal pour la répartition des éléments :

<div class="container">
  <div class="column col1">Colonne 1</div>
  <div class="column col2">Colonne 2</div>
  <div class="column col3">Colonne 3</div>
  <div class="column col4">Colonne 4</div>
</div>
Enter fullscreen mode Exit fullscreen mode
.container {
  display: flex; /* Activation de la flexbox */
  flex-direction: row; /* Choix de la direction principale */
  justify-content: center; /* Centrage des éléments sur l'axe principal */

  width: 100%;
  background-color: #fff9e6;
}

.column {
  background-color: #fbbe00;
  width: 100px;
  height: 50px;
  color: white;
}
Enter fullscreen mode Exit fullscreen mode

Ce qui nous donne :

Centrage avec une flexbox

En fait, la Flexbox est idéale pour aligner un nombre variable d'éléments sur un seul axe, sans définir au préalable le nombre de colonnes.

Mais il est tout de même possible de régler l'alignement sur l'axe secondaire (vertical dans notre cas 🙂) si, par exemple, notre .container occupait plus de place :

.container {
  /* ... */

  height: 100vh; /* Occuper toute la hauteur du viewport */
  align-items: center; /* Centrer sur l'axe secondaire */

  justify-content: space-between; /* (Autre exemple d'alignement sur l'axe principal) */

  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

Centrage avec une flexbox

...Et il est par ailleurs possible d'utiliser la propriété flex-wrap pour autoriser la création d'une ou plusieurs lignes supplémentaires dans le cas où nos éléments seraient trop grands pour tenir sur une seule ligne :

.container {
  /* ... */
  flex-wrap: wrap;
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

Flex wrap sur deux lignes

Vous noterez qu'en réalisant ce dernier exemple, j'ai volontairement introduit des tailles différentes sur les éléments 4 et 5. On constate alors que les flexboxs ne garantissent pas un alignement identique des colonnes sur plusieurs lignes 😕. La flexbox s'est juste contentée d'afficher les éléments les uns derrière les autres. C'est une limitation à prendre en compte.

Enfin, pour terminer ce tour d'horizon sur les Flexboxs, je mentionnerai la propriété notable flex sur les éléments enfants pour justement répondre à la problématique responsive "occuper intelligemment l'espace disponible" :

.container {
  display: flex; 
  flex-direction: row;
  align-items: center;
  height: 100vh;
  gap: 5px; /* (Espaces inter-éléments) */

  width: 100%;
  background-color: #fff9e6;
}

.column {
  background-color: #fbbe00;
  color: white;
}

.col2 {
  flex: 1; /* Petite capacité d'occupation d'espace */
}

.col3 {
  flex: 2; /* Moyenne capacité d'occupation d'espace */
}

.col4 {
  flex: 3; /* Grande capacité d'occupation d'espace */
}
Enter fullscreen mode Exit fullscreen mode

Répartition espace avec flex

La propriété flex nous permet donc de simplifier la répartition et le partage de l'espace disponible entre les éléments, ici en suivant un coefficient.

Mais attention à ne pas tout confondre : il s'agit bien ici d'étirer les éléments pour occuper l'espace, et non de leur attribuer une ou plusieurs colonnes ! On ne peut donc pas non plus espérer garantir un alignement, par exemple, entre plusieurs flexboxs sur une même colonne ! ...Ca, c'est le boulot des Grids !😋

Les Grids

L'usage classique

Parfois un peu "oublié", comme je vous le disais, depuis les multiples évolutions du CSS, le système de grid consiste à déclarer une grille 2D invisible sur laquelle on peut positionner les éléments enfants. Chaque case de cette grille étant dynamiquement extensible selon la taille du viewport et/ou des éléments.

Le système de Grid est idéal, par exemple, pour définir les dispositions fondamentales d'une page avec ce genre de structure :

<body>
  <header>
    <h1>Header</h1>
  </header>
  <aside>
    <h2>Sidebar</h2>
  </aside>
  <main>
    <h2>Main Title</h2>
    <p>Content content content...</p>
  </main>
</body>
Enter fullscreen mode Exit fullscreen mode

On peut alors typiquement déclarer une grille avec le grid-template-areas que je qualifierai d'assez visuel :

body {
  display: grid; /* Activation de la grille */
  grid-template-areas: /* Déclaration des zones de la grille */
    "header header header header"
    "sidebar content content content";

  grid-template-columns: repeat(4, 25%); /* Répartition des longueurs de nos 4 colonnes */
  grid-template-rows: 30% 70%; /* Répartition des hauteurs de nos 2 lignes */

  margin: 0; /* (Pour étendre notre grille... */
  height: 100vh; /* ...sur toute la page) */
}

header {
  grid-area: header; /* Attribution à la zone 'header' de la grille */
  background-color: #fbbe00;
  color: white;
}

aside {
  grid-area: sidebar;/* Attribution à la zone 'sidebar' de la grille */
  background-color: #fff9e6;
}

main {
  grid-area: content;/* Attribution à la zone 'content' de la grille */
  background-color: white;
}
Enter fullscreen mode Exit fullscreen mode

Usage basic d'une grid

La propriété grid-template-areas nous permet donc de définir un ensemble de colonnes et de lignes en leur donnant un nom arbitraire (et explicite tant qu'à faire ! 😊). Les balises enfants pouvant alors être attribuées aux zones ainsi nommées grâce à la propriété grid-area.

Auto flow

Si vous trouvez le système de Grid un peu trop "rigide" 🤖, sachez qu'il est également possible d'utiliser un layout automatique indépendamment du nombre d'éléments, un petit peu comme les flexboxs :

body {
  display: grid; /* Activation de la grille */

  grid-auto-flow: column; /* <== Répartition automatique sur les colonnes */

  margin: 0; /* (Pour étendre notre grille... */
  height: 100vh; /* ...sur toute la page) */
}
Enter fullscreen mode Exit fullscreen mode

Layout auto avec une grid

Il faut noter cependant, que si l'on spécifie les dimensions des colonnes et lignes avec un grid-template par exemple, la grille peut se permettre de modifier l'ordre d'apparition des éléments, et ce afin de privilégier ceux qui peuvent rentrer en premier dans les cases du template. Comportement qui peut être un poil déconcertant pour les non avertis...

Souvenez-vous : les Grids gèrent une répartition en 2 dimensions ! Contrairement aux flexboxs il n'y a pas d'axe principal !

Le saviez-vous ? Les propriétés justify-items et align-items peuvent aussi être utilisées sur les grids pour gérér l'alignement des éléments sur les axes verticaux et horizontaux, à la manière des Flexboxs !

Les Subgrids

Une propriété qui gagne à se faire connaître depuis quelques années ! (cf State of CSS 2023).

Admettons que vous ayez défini les colonnes principales de votre site (exactement comme nous venons de le voir tout au début avec les grid-template-areas). La hiérarchie HTML commence à grandir à force de rajouter du contenu.

Comment alors garantir que les balises n-ièmes sous-enfants sont correctement alignées sur nos colonnes définies à la racine du site, à l'image des Layout du Material Design 2 ?

C'est là que les subgrids interviennent ! Elles nous donnent la possibilité de se référer au template du parent direct (donc forcément, il faudra transmettre la subgrid à chaque niveau) :

main {
  grid-area: content; /* Attribution à la zone 'content' de la grille */

  display: grid;
  grid-template-columns: subgrid; /* <== Héritage du template de colonnes du parent ! */

  background-color: white;
}
Enter fullscreen mode Exit fullscreen mode

Ce qui nous permet de retrouver les 3 colonnes de la partie "content" parfaitement alignées avec les colonnes du parent. Le graal 😎!

Alignement colonnes subgrid

(Les zones violettes ont été ajoutées pour mettre en valeur les alignements)

Conclusion

Alors, les grids c'est has been ?

Comme nous avons pu le voir, si les grids ne sont pas dépréciées, c'est qu'il y a de bonnes raisons !

La Grid reste idéale pour définir des zones de base sur la page web, et garantir le même alignement 2D, inter-lignes ou inter-colonnes.

De son côté, la Flexbox est idéale pour définir plus simplement des alignements sur un seul axe ou partager l'espace disponible par rapport à un nombre variable d'éléments, et ce à un niveau plutôt secondaire, donc.

Au final, l'idée, c'est de savoir doser, comme une recette de cuisine :

  • des grids pour les fondations
  • quelques subgrids pour les sous-zones de la page
  • des flexboxs pour les alignements secondaires et/ou dynamiques
  • ...et le tout saupoudré de media queries pour adapter les dimensions et nombre de colonnes en fonction du support

Plus d'excuses pour être responsives avec les bons outils ! 🙂

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player