La Cascade

Un peu de tout sur CSS, HTML, SVG et JS,traduit du web anglophone
Rechercher

Comprendre CSS Grid : Grid template areas

par Rachel Andrew, 18 avril 2022, css, cssgrid, article original paru le 20 février 2020 dans Smashing Magazine

Dans cette nouvelle série, Rachel Andrew analyse la spécification CSS Grid Layout. Elle poursuit ici avec les zones de grille.


Avec Grid, on peut toujours placer les items entre une ligne de grille et une autre. Mais il existe une autre façon de décrire notre mise en page, une façon plus visuelle. Dans ce troisième volet de notre série nous allons voir comment utiliser la propriété grid-template-areas pour définir un placement sur la grille et nous découvrirons comme elle fonctionne réellement.

Décrire une mise en page avec grid-template-areas

La propriété grid-template-areas accepte pour valeur une ou plusieurs chaînes de caractères. Chacune, entourée de guillemets, représente une rangée de notre grille. Nous pouvons utiliser la propriété sur une grille définie avec grid-template-rows et grid-template-columns, ou nous pouvons créer notre mise en page, auquel cas toutes les rangées seront automatiquement dimensionnées.

La propriété et les valeurs qui suivent décrivent une grille comportant quatre zones — chacune s'étend sur deux pistes de colonnes et deux pistes de rangées. Une zone (area) peut s'étendre sur plusieurs pistes lorsqu'on en répète le nom dans toutes les cellules qu'on veut couvrir :

grid-template-areas: "one one two two"
                     "one one two two"
                     "three three four four"
                     "three three four four";

Les items sont placés dans la mise en page en étant nommés dans la propriété grid-area. Si nous voulons placer un élément ayant une classe test dans la zone de la grille qui s'appelle one, il suffit d'écrire :

.test {
  grid-area: one;
}

Regardons cela en action dans le codepen qui suit. J'ai quatre items, avec des classes nommées un à quatre (one to four), qui sont assignées aux zones de grille correspondantes via la propriété grid-area et qui s'affichent donc dans les boîtes correctes de la grille.

Si vous utilisez l'inspecteur Grid de Firefox, vous pouvez voir les noms des zones et les lignes de grille, montrant que chaque item s'étend en effet sur deux rangées et deux colonnes — le tout sans faire aucun positionnement basé sur les lignes pour l'item lui-même.

chaque item s'étend sur deux rangées et deux colonnes

Règles d'utilisation de grid-template-areas

Il ya des règles à suivre lorsqu'on crée une mise en page de cette façon. Ne pas les respecter rendra les valeurs invalides et notre mise en page ne fonctionnera pas. La première règle est que nous devons décrire une grille complète, chaque cellule de la grille doit être remplie.

Si l'on veut laisser une ou plusieurs cellules vides, on exprime ce choix en insérant un point . ou une série de points ... sans espace entre eux.

Si je change les valeurs de notre grille ainsi :

grid-template-areas: "one one two two"
                     "one one two two"
                     ". . four four"
                     "three three four four";

j'ai maintenant deux cellules sans contenu à l'intérieur. L'item three n'est affiché que dans la dernière rangée de la grille.

il y a maintenant un espace vide dans notre grille

Nous ne pouvons définir chaque zone qu'une seule fois, c'est à dire que nous ne pouvons utiliser cette propriété pour copier du contenu à deux endroits sur la grille ! Les valeurs qui suivent seraient invalides et la propriété dans son ensemble serait ignorée, car nous avons dupliqué la zone three :

grid-template-areas: "one one three three"
                     "one one two two"
                     "three three four four"
                     "three three four four";

On ne peut pas non plus créer une zone non-rectangulaire, la propriété ne peut pas être utilisée pour créer une zone en forme de T ou de L, et les valeurs ci-dessous sont également invalides :

grid-template-areas: "one one two two"
                     "one one one one"
                     "three three four four"
                     "three three four four";

Formater les chaînes de caractères

Dans mon CSS, j'aime bien afficher les valeurs de grid-template-area comme je le fais ci-dessus, avec chaque chaîne de caractères qui représente une rangée et chacune disposée en-dessous de la rangée précédente, car cela me donne une représentation visuelle de ma mise en page.

Pour améliorer encore la visualisation, on peut ajouter des espaces entre chaque cellule, mais aussi des points multiples pour les cellules vides, ainsi tout est bien aligné :

grid-template-areas: "one   one   two  two"
                     "one   one   two  two"
                     "..... ..... four four"
                     "three three four four";

Ceci étant, on peut, de manière tout à fait valide, aligner toutes les chaînes de caractères sur une seule ligne, on pourrait donc écrire :

grid-template-areas: "one one two two" "one one two two" "three three four four" "three three four four";

Expliquer grid-template-areas et grid-area

La raison pour laquelle chaque zone doit être un rectangle complet est qu'elle doit avoir la même forme que si elle avait été créée par un placement basé sur les lignes. Si nous poursuivons avec notre exemple précédent, nous pourrions réaliser cette mise en page avec des lignes de grille comme dans le codepen ci-dessous. Ici, j'ai créé ma grille comme avant. Cette fois par contre, j'ai utilisé les lignes de grille pour positionner via les propriétés (raccourcies) grid-column-start, grid-column-end, grid-row-start et grid-row-end.

Note : si vous avez lu mon précédent article Comprendre CSS Grid : les lignes Grid vous savez déjà qu'il est possible d'utiliser grid-area comme un raccourci pour déclarer les quatre lignes en une fois.

Cela signifie que nous pourrions aussi créer notre mise en page avec l'ordre de lignes suivant :

  • grid-row-start
  • grid-column-start
  • grid-row-end
  • grid-column-end
.one {
  grid-area: 1 / 1 / 3 / 3;
}

.two {
  grid-area: 1 / 3 / 3 / 5;
}

.three {
  grid-area: 3 / 1 / 5 / 3;
}

.four {
  grid-area: 3 / 3 / 5 / 5;
}

la propriété grid-area est intéressante en ce qu'elle peut prendre des numéros de ligne ou des noms de ligne. Mais il est important de comprendre comment elle fonctionne dans chaque mode.

Utiliser grid-area avec des numéros de ligne

Si vous utilisez la propriété grid-area avec des numéros de ligne, alors les lignes seront assignées dans l'ordre décrit ci-dessus.

Si vous omettez des valeurs — en ne fournissant qu'un, deux, ou trois numéros de ligne — les valeurs manquantes sont réglées sur auto ce qui signifie que la zone s'étendra sur une piste (ce qui est la valeur par défaut). Donc le CSS suivant placerait un item grid-row-start: 3 avec toutes les autres valeurs réglées sur auto, et donc, l'item serait auto-placé dans la première piste de colonne disponible, et s'étendrait sur une piste de rangée et une piste de colonne.

grid-area: 3;

Utiliser grid-area avec des idents

Si nous utilisons ident (qui est la façon pour Grid Layout d'appeller une zone nommée), alors la propriété grid-area prend aussi quatre lignes. Si vous avez des lignes nommées dans votre grille, comme décrit dans Comprendre CSS Grid : créer un container Grid, alors vous pouvez utiliser ces lignes nommées tout comme les lignes numérotées.

Attention cependant car, selon que vous utilisez ident avec des lignes nommées ou numérotées, le comportement sera différent dans le cas où vous omettez quelques lignes.

Ci-dessous, j'ai créé une grille avec des lignes nommées et utilisé grid-area pour placer un item (en omettant la valeur finale) :

.grid {
  display: grid;
  grid-template-columns:
      [one-start three-start] 1fr 1fr
      [one-end three-end two-start four-start] 1fr 1fr [two-end four-end];
  grid-template-rows:
    [one-start two-start] 100px 100px
    [one-end two-end three-start four-start] 100px 100px [three-end four-end];;
}

.two {
  grid-area: two-start / two-start / two-end;
}

Il nous manque donc le nom de ligne pour grid-column-end. La spécification dit que dans cette situation, grid-column-end doit utiliser une copie de grid-column-start. Si grid-column-end et grid-column-start sont identiques, alors la ligne finale est oubliée, et la valeur est réglée sur auto, donc l'item s'étend sur une piste, comme dans la version numérotée.

La même chose se produit si nous omettons la troisième valeur grid-row-end ; elle devient la même que grid-row-start et donc devient auto.

Jetez un œil à cet exemple codepen de la façon dont grid-area est utilisé et comment il change ensuite la mise en page de l'item :

Ceci explique pourquoi grid-area fonctionne avec une seule valeur ident représentant une zone nommée.

Quand nous créons une zone nommée avec la propriété grid-template-areas, le bord de chaque zone peut être référencé par un nom de ligne qui est le même que le nom de la zone utilisée. Dans notre cas, nous avons pu prendre notre zone nommée one et placer notre item en utilisant des lignes nommées comme suit :

.one {
  grid-row-start: one;
  grid-row-end: one;
  grid-column-start: one;
  grid-row-end: one;
}

Quand nous disons grid-area: one, nous omettons les trois dernières valeurs du raccourci grid-area ; elles finissent comme des copies de notre première valeur — toutes, dans notre cas deviennent one et l'item est placé exactement comme dans la version longue de notre css.

Le fonctionnement du nommage dans Grid layout est très intelligent et permet des choses bien intéressantes que j'ai décrites dans mes articles précédents Naming Things In CSS Grid Layout et Editorial Design Patterns With CSS Grid And Named Columns (en anglais).

Mettre en page des items avec grid-template-areas

Avec grid-template-areas, une cellule ne peut être occupée que par un seul nom, cependant nous pouvons toujours ajouter des items à la grille après avoir réalisé notre mise en page principale de cette manière. Pour cela, nous avons les lignes numérotées, comme d'habitude.

Dans l'exemple codepen suivant, j'ai ajouté un item supplémentaire et je l'ai placé par-dessus les items déjà présents en utilisant le positionnement basé sur les numéros de lignes.

Nous pouvons également utiliser les noms de lignes définis lorsque nous avons créé nos colonnes ou rangées. Mieux encore, nous aurons des noms de lignes créés par la formation des zones. Nous avons déjà vu comment nous pouvons obtenir quatre noms de lignes à partir du nom de la zone. Nous obtenons aussi une ligne de début au bord de chaque zone avec un -start ajouté au nom de la zone, et une ligne pour l'autre bord avec un -end ajouté.

Par conséquent, la zone nommée one a des lignes de début appelées one-start et de fin appelées one-end.

Nous pouvons ensuite utiliser ces noms implicites de lignes pour placer une item sur la grille. Cela peut être utile si on redéfinit la grille à plusieurs points de rupture (breakpoints), si nous voulons toujours que l'tem placé se trouve après un certain nom de ligne.

Utiliser grid template areas dans un design responsif

Je construis souvent des composants et je me rends compte que grid-template-areas peut être bien utile pour voir exactement, déjà dans le CSS, à quoi mon composant va ressembler. De plus, la redéfinition du composant pour plusieurs points de rupture est très simple, il suffit de redéfinir les valeurs de grid-template-areas, avec parfois en plus un changement du nombre de pistes de colonnes.

Dans le CSS qui suit, j'ai défini une mise en page à une seule colonne pour mon composant. Ensuite, à une largeur minimum de 600px, je redéfinis le nombre de colonnes ainsi que la valeur de grid-template-areas afin de créer une mise en page sur deux colonnes. Ce qui est bien avec cette approche, c'est qu'il suffit de regarder le CSS pour voir à quoi ressemble ma mise en page !

.wrapper {
  background-color: #fff;
  padding: 1em;
  display: grid;
  gap: 20px;
  grid-template-areas:
    "hd"
    "bd"
    "sd"
    "ft";

}

@media (min-width: 600px) {
  .wrapper {
    grid-template-columns: 3fr 1fr;
    grid-template-areas:
      "hd hd"
      "bd sd"
      "ft ft";
  }
}

header { grid-area: hd; }
article {grid-area: bd; }
aside { grid-area: sd; }
footer { grid-area: ft; }

Accessibilité

Il faut être prudent lorsqu'on utilise cette méthode et se rappeler qu'elle peut amener à une réorganisation du contenu qui peut se trouver déconnecté de l'ordre de la source. Un utilisateur naviguant avec la tabulation regarde l'écran tout en écoutant un texte dit par l'ordinateur, et ce dernier lit le contenu dans l'ordre où il figure dans la source HTML. Cela peut entraîner beaucoup de confusion pour l'utilisateur.

Résumé

Voilà tous les tuyaux à connaître sur les propriétés grid-template-area et grid-area pour créer des mises en page. Si vous ne l'avez pas déjà utilisée, essayez là. Je la trouve très utile notamment pour expérimenter et je m'en sers beaucoup pour mes prototypes — même si, pour une raison ou une autre, je suis amenée plus tard à utiliser une autre méthode pour la production.

Autres ressources externes

Articles de Rachel Andrew traduits dans La Cascade

Voir la page de Rachel Andrew et la liste de ses articles dans La Cascade.
Article original paru le 20 février 2020 dans Smashing Magazine
Traduit avec l'aimable autorisation de Smashing Magazine et de Rachel Andrew.
Copyright Smashing Magazine © 2020