Grille CSS : la mise en page Table est de retour. Soyez présent et soyez carré

TL;DR

Si vous connaissez Flexbox, Grid devrait vous sembler familier. Rachel Andrew gère un excellent site Web dédié à la grille CSS pour vous aider à vous lancer. La grille est désormais disponible dans Google Chrome.

Flexbox ? Grille ?

Au cours des dernières années, CSS Flexbox est devenu largement utilisé et la compatibilité avec les navigateurs est très bonne (sauf si vous faites partie des pauvres âmes qui doivent prendre en charge IE9 et versions antérieures). Flexbox a facilité de nombreuses tâches de mise en page complexes, comme l'espacement équilibré entre les éléments, les mises en page de haut en bas ou le Saint Graal de la magie CSS : le centrage vertical.

Il n'existe aucun moyen d'aligner des éléments sur plusieurs conteneurs Flexbox.

Malheureusement, les écrans ont généralement une deuxième dimension à prendre en compte. À moins de vous occuper vous-même du dimensionnement des éléments, malheureusement, vous ne pouvez pas avoir à la fois un rythme vertical et horizontal en utilisant simplement Flexbox. C'est là que la grille CSS vient à la rescousse.

CSS Grid est en cours de développement et est mis en avant dans la plupart des navigateurs depuis plus de cinq ans. Des temps supplémentaires ont été consacrés à l'interopérabilité afin d'éviter un lancement de bugs comme celui de Flexbox. Par conséquent, si vous utilisez la grille pour implémenter votre mise en page dans Chrome, vous obtiendrez probablement le même résultat dans Firefox et Safari. Au moment de la rédaction de cet article, l'implémentation de Grid dans Edge de Microsoft est obsolète (identique à celle déjà présente dans IE11) et la mise à jour est en cours d'examen.

Malgré les similitudes en termes de concept et de syntaxe, ne considérez pas Flexbox et la grille comme des techniques de mise en page concurrentes. La grille s'organise en deux dimensions, tandis que Flexbox s'organise en une seule. Il existe une synergie lorsque vous combinez les deux.

Définir une grille

Pour vous familiariser avec les propriétés individuelles de Grid, je vous recommande vivement de consulter Grid By Example de Rachel Andrew ou la fiche récapitulative de CSS Tricks. Si vous connaissez Flexbox, vous devriez connaître un grand nombre de propriétés et leur signification.

Examinons une mise en page de grille standard à 12 colonnes. La mise en page classique à 12 colonnes est populaire, car le nombre 12 est divisible par 2, 3, 4 et 6, et est donc utile pour de nombreuses conceptions. Implémentons cette mise en page:

Il n'est pas possible d'aligner des éléments dans plusieurs conteneurs Flexbox.

Commençons par notre code de balisage:

<!DOCTYPE html>
<body>
    <header></header>
    <nav></nav>
    <main></main>
    <footer></footer>
</body>

Dans notre feuille de style, nous commençons par développer notre body afin qu'il couvre l'ensemble du viewport et le transformons en conteneur de grille:

html, body {
    width: 100vw;
    min-height: 100vh;
    margin: 0;
    padding: 0;
}
body {
    display: grid;
}

Nous utilisons maintenant la grille CSS. Parfait !

L'étape suivante consiste à implémenter les lignes et les colonnes de notre grille. Nous pourrions implémenter les 12 colonnes de notre maquette, mais comme nous n'utilisons pas toutes les colonnes, cela rendrait notre CSS inutilement désordonné. Par souci de simplicité, nous allons implémenter la mise en page de la manière suivante:

Exemple de mise en page simplifiée

La largeur de l'en-tête et du pied de page est variable, et le contenu est variable dans les deux dimensions. La barre de navigation sera également variable dans les deux dimensions, mais nous allons lui imposer une largeur minimale de 200 pixels. (Pourquoi ? Pour présenter les fonctionnalités de CSS Grid, bien sûr.)

Dans la grille CSS, les ensembles de colonnes et de lignes sont appelés pistes. Commençons par définir notre premier ensemble de pistes, les lignes:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
}

grid-template-rows prend une séquence de tailles qui définissent les lignes individuelles. Dans ce cas, la première ligne a une hauteur de 150 pixels et la dernière une hauteur de 100 pixels. La ligne du milieu est définie sur auto, ce qui signifie qu'elle s'ajuste à la hauteur nécessaire pour accueillir les éléments de grille (les enfants du conteneur de grille) de cette ligne. Comme notre corps est étiré sur toute la fenêtre d'affichage, la piste contenant le contenu (jaune dans l'image ci-dessus) remplira au moins tout l'espace disponible, mais s'agrandira (et fera défiler le document) si nécessaire.

Pour les colonnes, nous souhaitons adopter une approche plus dynamique: nous voulons augmenter (et réduire) à la fois la navigation et le contenu, mais nous voulons que la navigation ne rétrécisse jamais en dessous de 200 pixels et nous voulons que le contenu soit plus grand que la barre de navigation. Dans Flexbox, nous utilisons flex-grow et flex-shrink, mais dans Grid, c'est un peu différent:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
}

Nous définissons deux colonnes. La première colonne est définie à l'aide de la fonction minmax(), qui prend deux valeurs: la taille minimale et maximale de ce canal. (comme min-width et max-width à la fois). La largeur minimale est, comme nous l'avons vu précédemment, de 200 pixels. La largeur maximale est de 3fr. fr est une unité spécifique à la grille qui vous permet de distribuer l'espace disponible aux éléments de la grille. fr signifie probablement "fraction unit" (unité fractionnaire), mais peut aussi signifier "free unit" (unité libre) prochainement. Nos valeurs ici signifient que les deux colonnes vont se développer pour remplir l'écran, mais la colonne de contenu sera toujours trois fois plus large que la colonne de navigation (à condition que la colonne de navigation reste plus large que 200 px).

Bien que le placement de nos éléments de grille ne soit pas encore correct, la taille des lignes et des colonnes se comporte correctement et produit le comportement que nous recherchions:

Placer les éléments

L'une des fonctionnalités les plus puissantes de Grid est de pouvoir placer des éléments sans tenir compte de l'ordre DOM. (Bien que, comme les lecteurs d'écran naviguent dans le DOM, nous vous recommandons vivement de faire attention à la manière dont vous réorganisez les éléments pour une accessibilité optimale.) Si aucun placement manuel n'est effectué, les éléments sont placés dans la grille dans l'ordre DOM, de gauche à droite et de haut en bas. Chaque élément occupe une cellule. L'ordre dans lequel la grille est remplie peut être modifié à l'aide de grid-auto-flow.

Comment placer les éléments ? Le moyen le plus simple de placer des éléments de grille consiste à définir les colonnes et les lignes qu'ils couvrent. Grid propose deux syntaxes pour ce faire : dans la première syntaxe, vous définissez les points de début et de fin. Dans le second, vous définissez un point de départ et une étendue:

header {
    grid-column: 1 / 3;
}
nav {
    grid-row: 2 / span 2;
}
Emplacement défini manuellement

Nous voulons que notre en-tête commence dans la première colonne et se termine avant la troisième colonne. La barre de navigation doit commencer sur la deuxième ligne et s'étendre sur deux lignes au total.

Techniquement, nous avons terminé d'implémenter notre mise en page, mais je souhaite vous montrer quelques fonctionnalités pratiques que Grid met à votre disposition pour faciliter le placement. La première fonctionnalité est que vous pouvez nommer les bordures de vos pistes et utiliser ces noms pour l'emplacement:

body {
    display: grid;
    grid-template-rows: 150px [nav-start] auto 100px [nav-end];
    grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
    grid-column: header-start / header-end;
}
nav {
    grid-row: nav-start / nav-end;
}

Le code ci-dessus génère la même mise en page que le code précédent.

La fonctionnalité de dénomination de régions entières dans votre grille est encore plus puissante:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
    grid-template-areas: "header header"
                        "nav    content"
                        "nav    footer";
}
header {
    grid-area: header;
}
nav {
    grid-area: nav;
}

grid-template-areas accepte une chaîne de noms séparés par un espace, ce qui permet au développeur d'attribuer un nom à chaque cellule. Si deux cellules adjacentes portent le même nom, elles seront fusionnées dans la même zone. Vous pouvez ainsi fournir plus de sémantique à votre code de mise en page et rendre les requêtes multimédias plus intuitives. Encore une fois, ce code génère la même mise en page qu'auparavant.

Y a-t-il autre chose ?

Oui, il y a beaucoup trop de choses à couvrir dans un seul article de blog. Rachel Andrew, également GDE, est un expert invité dans le groupe de travail CSS. Il travaille avec lui depuis le début pour s'assurer que la grille simplifie la conception Web. Elle a même écrit un livre à ce sujet. Son site Web Grid By Example est une ressource précieuse pour vous familiariser avec Grid. De nombreuses personnes pensent que Grid est une étape révolutionnaire pour la conception Web. Il est désormais activé par défaut dans Chrome, vous pouvez donc commencer à l'utiliser dès aujourd'hui.