Construire une grille produits avec CSS Grid aujourd'hui
Aaah les grilles produits. Que le premier ou la première n’ayant jamais bataillé de toute sa carrière pour réaliser un affichage propre et flexible d’une grille produits en pourcentage me jette la première pierre.
Mais si, souvenez-vous du brief : une grille produits à largeur fluide et dont le nombre d’éléments s’adapte en fonction de la largeur, éléments qui d’ailleurs doivent (dans l’idéal) avoir une largeur minimale mais aussi maximale afin de conserver l’homogénéité de l’interface (et ne pas risquer l’ire de votre directeur•trice artistique). J’oubliais : la grille s’affiche en colonnes mais aussi… sur une colonne unique (pour afficher plus de détails sur le produit par exemple).
Ça c’était avant
Il y a quelque temps (disons entre 10 et 15 ans), pour répondre à cette problématique nous aurions fait un joli tableau HTML. Avantage : c’était flexible en largeur et presque toujours bien calé (hum). Inconvénients : le balisage un peu lourd, le nombre d’éléments par ligne figé et la construction de la dernière ligne loin d’être optimale à gérer lors de la phase de dynamisation (des amateurs de calcul de l’attribut rowspan
dynamiquement en fonction du nombre de produits dans la grille ?). Et côté sémantique… on repassera.
Ensuite, pendant longtemps, il y a eu une période partagée entre l’utilisation des flottants et leurs classes utilitaires pour éviter un effet d’escalier disgracieux, et l’utilisation des inline-block
avec des techniques (qui relevaient d’ailleurs plus du bricolage que de la science pure) à base de font-size: 0;
pour faire disparaître les espacements naturels entre les éléments inline.
Je vais vous gâcher la surprise, mais j’étais de la première école. Devoir mettre à 0 une taille de texte pour positionner un bloc me paraissait (et me paraît toujours) contre nature. Pour moi, cela a toujours relevé du hack pur et simple (même si, avouons-le cela fonctionnait… tant qu’on ne voulait pas faire d’héritage sur la taille de police bien entendu).
Et un beau jour un nouveau venu fait son entrée : flexbox. Et nous voici donc avec un outil qui nous permet enfin d’avoir des blocs qui agencent leur taille en fonction de leur contenu sans jamais dépasser leur conteneur, qui nous permet de redistribuer l’espace restant entre les blocs, de les réordonner sans toucher au DOM, de centrer le contenu verticalement… Et bien sûr il est tout à fait possible de s’en servir pour de la mise en page même s’il est plus adapté pour les petits éléments.
Et voilà qu’un récent ajout vient redistribuer toutes les cartes : CSS Grid. Et pour notre plus grand bonheur, il a clairement été pensé pour faire du layout.
Retour vers le futur
Nous voici donc de retour à aujourd’hui avec le support toujours meilleur de CSS Grid.
CSS Grid – vous en avez forcément déjà entendu parler étant donnée l’agitation que cela provoque depuis quelque temps déjà – est le dernier outil en date pour réaliser l’agencement de nos pages web.
CSS Grid a pour principe fondateur l’agencement d’éléments en fonction... d’une grille. Il est ainsi possible de déterminer avec précision les coordonnées exactes de nos éléments sur la grille – grille que nous aurons préalablement définie : nombre de colonnes, de lignes, hauteurs et largeurs, gouttières entre les cellules, etc ou encore de laisser la grille s'agencer automatiquement.
Dans cet article, nous nous attarderons sur l’utilisation de CSS Grid dans le cas qui nous occupe : la mise en place d’une grille de catalogue produits. Je laisse volontairement les détails concernant les bases de l’utilisation de Grid de côté, d’autres l’ayant déjà fait.
Mise en route
Précisons un point important tout de suite : oui, il est tout à fait possible d’utiliser Grid en production aujourd’hui. Cependant, et comme toujours, le périmètre navigateurs de votre projet va avoir un impact sur votre manière de l’implémenter et quelles solutions de substitution vous allez devoir mettre en place. On reviendra plus loin notamment sur le cas Internet Explorer/MS Edge qui, si on se fie à caniuse.com, supportent CSS Grid. On verra que la réalité est plus complexe que cela.
Revenons à nos moutons. Pour rappel, voici ce que nous essayons d’obtenir :
- une grille produits ;
- répartie sur plusieurs lignes et colonnes ;
- composée d’un nombre non défini d’éléments par ligne ;
- éléments qui doivent être fluides en largeur ;
- et sans employer javascript bien entendu.
Voici la structure HTML à partir de laquelle nous allons travailler :
Et quelques styles de base :
Vous pouvez voir l’exemple sur cette page.
Pas très engageant pour l’instant. Ajoutons donc un peu de CSS Grid par dessus tout ça et voyons ce que ça donne.
Dans cet exemple, l’affichage en grille est activé à l’aide de la valeur grid
de la propriété display
. Cependant, pour fonctionner, Grid a besoin d’autres propriétés : il nous faut définir les colonnes (à l’aide de grid-template-columns
) et les lignes (avec grid-template-rows
).
grid-template-columns
accepte principalement des valeurs de dimension séparées par des espaces, chaque valeur définissant une colonne. Ainsi dans l’exemple ci-dessus, nous définissons une colonne unique prenant toute la largeur de la grille. L’unité fr
a été introduite avec Grid afin de pouvoir exprimer des largeurs en fractions de la grille. Cette unité se comporte comme la valeur numérique de flex-grow
. Ainsi, l’exemple suivant produira une grille de deux colonnes dont la seconde est deux fois plus large que la première :
La dernière propriété que nous ajoutons, grid-gap
, permet de définir les gouttières entre les cellules de la grille. Il s’agit d’une propriété raccourcie, acceptant une valeur (pour les gouttières des lignes et des colonnes) ou deux sous cette forme grid-gap: <lignes> <colonnes>;
.
Agencement automatique des cellules
Nous savons maintenant construire une grille avec un nombre défini de colonnes. Mais le brief initial incluait un ajustement automatique des colonnes et des lignes en fonction du nombre d’éléments les constituant.
C’est là qu’entre en jeu l’algorithme d’agencement automatique de CSS Grid. C’est probablement un des outils de mise en page les plus puissants dont nous disposons à l’heure actuelle.
Changeons un peu notre précédente déclaration :
La fonction repeat()
permet de répéter un certain nombre de fois un template de ligne ou de colonnes. Le premier paramètre représente le nombre de répétitions, le second le template de colonne ou de ligne. Dans l’exemple ci-dessus, on crée une grille de 4 colonnes de 300px de large chacune, l’espace restant n’étant pas (encore) redistribué.
Afin de rendre cette création de colonnes plus souple et plus dynamique, CSS Grid nous apporte d’autres outils : auto-fill
/auto-fit
et minmax()
.auto-fill
et auto-fit
sont au cœur de l’agencement dynamique de la grille. En effet, en appliquant un de ces deux mots-clefs en lieu et place du nombre de répétitions, on indique au navigateur d’essayer de faire entrer un maximum de colonnes dans la largeur de la grille, rendant ainsi la grille complètement fluide et donc plus robuste.
A ce stade, notre grille est fluide, le nombre d’éléments par ligne est également fluide. Il ne nous reste donc plus qu’à rendre les éléments eux-même fluides.
C’est en utilisant la fonction minmax()
que nous allons y parvenir. minmax()
permet de poser des bornes pour la largeur de nos colonnes, tout en redistribuant l’espace restant entre toutes les colonnes équitablement (à la manière de flexbox). Ainsi l’expression suivante indiquera au navigateur que nos colonnes doivent être comprises entre 200 et 350px de large, espace supplémentaire redistribué compris :
Notre code mis à jour devient donc :
Un dernier ajout a fait son apparition : 1fr
pour la borne supérieure de la taille de nos colonnes. Cela nous permet d’avoir des colonnes qui font au minimum 300px de large mais qu’aucune ne soit plus grande que les autres.
Gestion de l’amélioration progressive
Nous voici pratiquement à la fin de notre exercice. Il ne reste plus qu’à s’occuper des navigateurs ne supportant pas CSS Grid ou supportant une ancienne version de la spécification.
J’en parlais plus haut, Internet Explorer et les premières versions de MS Edge (< 16) supportent CSS Grid (en fait c’est même Microsoft qui a publié la première proposition pour Grid). Mais ils supportent l’ancienne version de la spécification. Il va donc falloir s’en accommoder.
Avant de passer à la partie technique, quelques précisions sur le support de Grid dans IE 10, 11 et MS Edge < 16 s’imposent. Comme l’écrivait Rachel Andrew dès 2016, il existe diverses incompatibilités entre la version de CSS Grid implémentée dans ces navigateurs et celle de la spécification plus récente :
- pas de support pour les gouttières : il faudra les simuler par des colonnes/lignes vides ;
- pas d’agencement automatique ;
- certaines propriétés portent le même nom mais ne se comportent pas de la même façon, rendant plus complexe une éventuelle amélioration progressive.
Je vous laisse consulter l’article de Rachel Andrew pour plus de détails sur ces incompatibilités mais s’il y a une chose à retenir c’est la suivante : un usage basique de CSS Grid fonctionnera dans ces navigateurs. Au delà, il faudra inclure cette famille de navigateurs dans votre solution de fallback.
La mise en place de l’amélioration progressive pour CSS Grid est plutôt simple à gérer grâce à l’emploi de @supports
. Le support d’Internet Explorer et de MS Edge < 16 étant préfixé il est ainsi aisé de les exclure des propriétés avancées de Grid :
Et voilà ! Nous avons notre grille produits avec CSS Grid et amélioration progressive sans JavaScript.
La suite
Comme on a pu le voir, CSS Grid est un outil vraiment performant pour la mise en page. Nous n’avons cependant fait qu’effleurer la surface de ce dont il est capable : il est par exemple possible de nommer des zones et d’y affecter des éléments directement, d’ajuster la largeur des colonnes en fonction de leur contenu, etc.
CSS évolue. A nous de nous approprier ces nouveaux outils et d’en exploiter tout le potentiel !
Aller plus loin
Si CSS Grid vous intrigue, je vous conseille de suivre Rachel Andrew et Jen Simmons qui aujourd’hui sont les références en la matière. Quelques autres liens :
- Spécification de CSS Grid
- Support actuel de CSS Grid
- Référence complète de CSS Grid chez CSS Tricks
- Exemple d’emplois de CSS Grid
- Article de Rachel Andrew sur la compatibilité des diverses versions de CSS Grid
- Détail du support de CSS Grid dans Internet Explorer
- Quelques exemples d’amélioration progressive chez Rachel Andrew