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

Résumé

Si vous connaissez déjà Flexbox, la fonctionnalité Grid ne devrait pas vous gêner. Rachel Andrew gère un excellent site Web dédié à la grille CSS pour vous aider à démarrer. La grille est désormais disponible dans Google Chrome.

Flexbox? Grille ?

Ces dernières années, CSS Flexbox s'est largement utilisé et la compatibilité avec les navigateurs est particulièrement bonne (sauf si vous faites partie des pauvres qui doivent prendre en charge IE9 ou version antérieure). Flexbox simplifie de nombreuses tâches de mise en page complexes, comme l'espacement équidistant entre les éléments, les mises en page de haut en bas ou le point central de la magie CSS : le centrage vertical.

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

Mais hélas, les écrans ont généralement une deuxième dimension dont nous devons nous préoccuper. À moins de devoir dimensionner vous-même les éléments, vous ne pouvez malheureusement pas avoir un rythme vertical et horizontal à la fois en utilisant simplement Flexbox. C'est là que la grille CSS va à la rescousse.

La grille CSS est en cours de développement, derrière un indicateur dans la plupart des navigateurs depuis plus de cinq ans, et a consacré du temps supplémentaire à l'interopérabilité pour éviter un lancement buggé comme celui de Flexbox. Ainsi, 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 ce document, l'implémentation Microsoft Edge de Grid est obsolète (identique à celle déjà présente dans IE11) et la mise à jour est en cours de considération.

Malgré les similitudes en termes de concept et de syntaxe, ne considérez pas Flexbox et Grid comme des techniques de mise en page concurrentes. La grille s'organise en deux dimensions, tandis que Flexbox est réparti en une seule. L'utilisation des deux ensemble offre une synergie.

Définir une grille

Pour vous familiariser avec les propriétés individuelles de la grille, je vous recommande vivement d'utiliser Grid By Example de Rachel Andrew ou l'aide-mémoire de CSS Tricks. Si vous connaissez Flexbox, vous devriez connaître de nombreuses propriétés et leur signification.

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

Il n'est pas possible d'aligner des éléments sur 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 body afin qu'il couvre l'ensemble de la fenêtre d'affichage, puis nous 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 dans 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 comme suit:

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. L'élément de navigation sera variable dans les deux dimensions, mais nous allons lui imposer une largeur minimale de 200 pixels. (Pourquoi ? Pour montrer les caractéristiques de la grille CSS, bien entendu.)

Dans la grille CSS, l'ensemble des colonnes et des lignes s'appelle des 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 accepte une séquence de tailles qui définissent les lignes individuelles. Dans ce cas, nous attribuons une hauteur de 150 pixels à la première ligne et une hauteur de 100 pixels à la dernière. La ligne du milieu est définie sur auto, ce qui signifie qu'elle s'adapte à la hauteur nécessaire pour accueillir les éléments de la grille (les enfants du conteneur de la grille) de cette ligne. Comme le corps est étiré sur l'ensemble de la fenêtre d'affichage, la piste contenant le contenu (en 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 voulons adopter une approche plus dynamique: nous voulons que la navigation et le contenu augmentent (et diminuent), mais que la taille de nav ne soit jamais réduite en dessous de 200 pixels et que nous voulons que le contenu soit plus grand que nav. Dans Flexbox, nous utiliserions 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 accepte deux valeurs: la taille minimale et la taille maximale de cette piste. (Cela ressemble à min-width et max-width à la fois.) Comme nous l'avons vu précédemment, la largeur minimale est de 200 pixels. La largeur maximale est de 3fr. fr est une unité spécifique à la grille qui vous permet de répartir l'espace disponible entre les éléments de la grille. fr signifie probablement "unité de fraction", mais pourrait également signifier "unité libre prochainement". Les valeurs que nous saisissons ici signifient que les deux colonnes s'agrandissent pour remplir l'écran, mais que 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 pixels).

Bien que l'emplacement des éléments de notre grille ne soit pas encore correct, la taille des lignes et des colonnes se comporte correctement et donne le comportement souhaité:

Placer les éléments

L'une des fonctionnalités les plus puissantes de la grille est de pouvoir placer des éléments sans tenir compte de l'ordre DOM. Toutefois, comme les lecteurs d'écran naviguent dans le DOM, nous vous recommandons vivement de faire attention à la façon dont vous réorganisez les éléments pour qu'ils soient correctement accessibles. 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.

Alors, comment placer les éléments ? Le moyen le plus simple de placer des éléments de grille consiste sans doute à définir les colonnes et les lignes qu'ils couvrent. La grille propose deux syntaxes pour ce faire : dans la première syntaxe, vous définissez les points de départ et d’arrivée. Dans la deuxième, vous définissez un point de départ et un segment:

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 3e colonne. Notre 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 veux vous montrer quelques fonctionnalités pratiques que Grid vous offre pour faciliter le placement. La première fonctionnalité vous permet de nommer les bordures de votre piste et d'utiliser ces noms pour leur 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 possibilité de nommer des régions entières dans votre grille est encore plus efficace:

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 des espaces, 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 ajouter plus de sémantique à votre code de mise en page et rendre les requêtes média plus intuitives. Là encore, ce code génère la même mise en page qu'auparavant.

Y a-t-il autre chose ?

Oui, oui, il y en a beaucoup trop à aborder dans un seul article de blog. Rachel Andrew, également GDE, est une experte invitée au sein du groupe de travail CSS. Elle collabore avec eux depuis le début pour s'assurer que Grid simplifie la conception Web. Elle a même écrit un livre dessus. Son site Web Grid By Example est une ressource précieuse pour se familiariser avec Grid. De nombreux utilisateurs pensent que la grille est une étape révolutionnaire de la conception Web. Elle est désormais activée par défaut dans Chrome, ce qui vous permet de l'utiliser dès aujourd'hui.