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

Surma
Surma

Résumé

Si vous connaissez bien Flexbox, la grille devrait vous sembler familière. 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 ?

Ces dernières années, l'option CSS Flexbox est largement utilisée et la compatibilité avec les navigateurs semble très satisfaisante (sauf si vous faites partie des mauvaises personnes devant prendre en charge IE9 et les 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'est pas possible d'aligner des éléments dans plusieurs conteneurs Flexbox.

Mais hélas, les écrans ont généralement une deuxième dimension dont nous devons nous soucier. À 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 va intervenir.

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. 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 était obsolète (la même que celle qui était 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 le propose en une seule. Il existe une synergie lorsque vous utilisez les deux ensemble.

Définir une grille

Pour me familiariser avec les propriétés individuelles de la grille, je vous recommande vivement l'atelier Grid By Example de Rachel Andrew ou l'aide-mémoire de CSS Tricks. Si vous connaissez Flexbox, vous devriez connaître un grand nombre de ses propriétés et de 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 body pour qu'il couvre toute la fenêtre d'affichage et la 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'utilisions 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

L'en-tête et le pied de page ont une largeur variable, et le contenu des deux dimensions. La navigation sera également variable dans les deux dimensions, mais nous allons lui imposer une largeur minimale de 200 px. (Pourquoi ? Pour montrer les fonctionnalités de la grille CSS, évidemment.)

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. Notre corps étant é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 accepte deux valeurs: la taille minimale et la taille maximale de cette piste. (comme 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 "fraction unit", mais peut également désigner bientôt une unité libre. Nos valeurs signifient que les deux colonnes seront agrandies 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 l'emplacement 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 visions:

Positionner les articles

L'une des fonctionnalités les plus puissantes de la grille consiste à pouvoir placer des éléments sans tenir compte de l'ordre des éléments DOM. (Toutefois, étant donné que les lecteurs d'écran parcourent le DOM, nous vous recommandons vivement de faire attention à la façon dont vous réorganisez les éléments pour être correctement accessibles.) Si aucun placement manuel n'est effectué, les éléments sont placés dans la grille par ordre DOM, disposés 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 est de définir les colonnes et les lignes qu'ils couvrent. La grille offre deux syntaxes pour ce faire : dans la première syntaxe, vous définissez les points de départ et d'arrivée. Dans le second, définissez un point de départ et un intervalle:

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

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

Techniquement, nous avons terminé l'implémentation de notre mise en page, mais je veux vous montrer quelques fonctionnalités pratiques fournies par la grille pour faciliter le placement. La première fonctionnalité vous permet de nommer les frontières de votre suivi et d'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 permet d'obtenir la même mise en page que le code précédent.

Plus efficace encore est la fonctionnalité permettant de nommer des régions entières dans votre grille:

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. De cette façon, vous pouvez fournir 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, il y a bien trop de choses à aborder 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 sur ce sujet. Son site Web Grid By Example est une ressource précieuse pour se familiariser avec Grid. De nombreuses personnes pensent que Grid est une étape révolutionnaire de la conception Web. Elle est désormais activée par défaut dans Chrome pour que vous puissiez l'utiliser dès aujourd'hui.