Creuser dans la propriété d'affichage : grilles jusqu'en bas

Publié: 2022-03-10
Résumé rapide ↬ Poursuivant une série sur la propriété d' display dans CSS, cette fois Rachel Andrew examine ce qui se passe lorsque vous utilisez la grille comme valeur d'affichage, avec des informations supplémentaires sur la façon dont la sous-grille modifie ce comportement.

Aujourd'hui, nous allons examiner ce qui se passe lorsque nous utilisons display: grid et comment nous pourrions utiliser la nouvelle valeur de sous-grille de grid-template-columns et grid-template-rows pour permettre des grilles tout au long de notre balisage , qui se rapportent les uns aux autres.

Cet article fait partie d'une série qui examine divers aspects de la propriété display CSS et fait suite aux deux premiers articles :

  1. Les deux valeurs de display
  2. Génération de boîtes
  3. Grilles tout le long

Que se passe-t-il lorsque nous créons un conteneur Grid ?

CSS Grid Layout est activé en utilisant display: grid . Si vous avez lu le premier article de cette série, vous saurez que cette propriété à valeur unique signifie en réalité display: block grid . Nous obtenons une boîte de niveau bloc qui est définie comme un conteneur de grille , avec des enfants directs qui sont des éléments de grille et participent à la disposition de la grille.

Si vous jetez un coup d'œil à la spécification d'affichage, vous le verrez dans le tableau qui définit toutes les différentes valeurs pour display . Les mots conteneur de grille sont liés à la définition d'un conteneur de grille dans la spécification de grille. Par conséquent, pour savoir ce que cela signifie réellement, nous devons aller voir là-bas. Lorsque nous le faisons, nous obtenons des éclaircissements utiles sur le comportement d'un conteneur de grille.

Plus après saut! Continuez à lire ci-dessous ↓

On dit qu'un conteneur de grille établit un contexte de formatage de grille qui est similaire à un contexte de formatage de bloc (BFC). J'ai écrit un guide détaillé sur le contexte de formatage des blocs. Dans cet article, vous découvrirez deux choses sur un BFC qui sont identiques pour un contexte de formatage de grille. Les flottants n'empiètent pas sur le conteneur de la grille et les marges du conteneur ne s'effondrent pas avec celles du contenu.

Il y a des différences, cependant, seulement une fois que nous sommes entrés dans le conteneur de la grille. Les enfants d'un conteneur de grille et ne participant pas à la mise en page en bloc et en ligne, ce sont des éléments de grille et participent donc à la mise en page de la grille. Cela signifie que certaines choses auxquelles nous sommes habitués dans la mise en page en bloc et en ligne ne sont pas vraies.

Si un élément de la mise en page est flottant ou effacé, les propriétés float et clear n'ont pas d'effet une fois que l'élément devient un élément de grille. La propriété vertical-align n'a aucun effet et les pseudo-éléments ::first-letter et ::first-line ne peuvent pas être utilisés.

Le fait qu'un élément ne puisse pas être à la fois flottant et élément de grille est utile pour créer des replis. Lors de la création d'un repli pour les navigateurs qui ne prennent pas en charge la grille à l'aide de flottants (lorsque la grille est prise en charge), vous n'avez rien à faire de spécial : le flottant est écrasé.

Je décris cette approche dans mon article sur la prise en charge des navigateurs sans grille. Il y a des situations où le comportement s'est avéré problématique, bien que ces problèmes puissent être résolus en utilisant une autre partie de CSS comme décrit dans cet article déballant un problème avec la grille et les flottants, "Mises en page éditoriales, exclusions et grille CSS".

Cela dit, si nous ne faisons rien d'autre que de changer la valeur de display en grid , nous ne verrons pas beaucoup de différence dans notre mise en page. Les enfants directs sont des éléments de grille, cependant, par défaut, nous nous retrouvons avec une grille à une colonne. Une grille a toujours une colonne et une ligne. Le reste des lignes que nous pouvons voir après cela sont des lignes implicites, c'est-à-dire des lignes créées pour contenir le contenu.

Jeu de cartes disposées les unes sous les autres dans une seule colonne.
Lorsque nous créons un conteneur de grille sans colonnes, nous obtenons une grille à une colonne. ( Grand aperçu )

Nous pouvons commencer à former quelque chose qui ressemble plus à une grille en donnant une valeur à la propriété grid-template-columns . La propriété prend une liste de pistes comme valeur ; si je lui donne trois pistes 1fr, nous nous retrouvons maintenant avec une grille à trois colonnes, et l'utilisation de la propriété gap me donne un espacement entre ces cartes.

Nous avons maintenant quelque chose qui nous ressemble à une grille :

Cartes disposées en trois colonnes et deux rangées
Nous définissons quelques pistes de colonne et un espace pour obtenir une disposition de grille évidente ( Grand aperçu )

Chacun des éléments de la grille dans notre exemple a ses propres enfants. Les cartes ont des en-têtes et des pieds de page et une zone pour le contenu principal de la carte. Ces enfants sont des éléments de grille, mais leurs enfants sont revenus à la mise en page en bloc et en ligne. L'en-tête, la zone de contenu et le pied de page ne font pas de grille comme des choses. En effet, lorsque nous modifions la valeur de display en grid , il n'hérite pas mais seuls les enfants deviennent des éléments de grille ; leurs enfants reviennent à la disposition des blocs.

Grilles imbriquées

Si une carte a plus de contenu que les autres cartes, les cartes de cette rangée deviennent plus hautes. La valeur initiale de align-items pour les éléments de la grille est stretch . Nos cartes s'étendent sur toute la hauteur. Les éléments à l'intérieur, cependant, sont en flux normal de blocs et en ligne et ne s'étirent donc pas comme par magie pour remplir la carte. (C'est pourquoi dans l'image ci-dessus, vous pouvez voir que les cartes avec moins de contenu ont un espace en bas.)

Si nous le voulions (afin que ce pied de page soit toujours en bas), nous pourrions également faire de notre élément de grille une grille. Dans ce cas, une grille à une seule colonne est tout ce dont nous avons besoin. Nous pouvons ensuite définir des pistes de ligne, donnant la zone dans laquelle se trouve la div avec une classe de contenu, une taille de piste de 1fr . Cela lui fait occuper tout l'espace disponible dans le conteneur et pousse le pied de page vers le bas de la carte.

Voir le Pen [display: subgrid is not what we want](https://codepen.io/rachelandrew/pen/PvQzeG) par Rachel Andrew.

Voir l'affichage du stylet : la sous-grille n'est pas ce que nous voulons par Rachel Andrew.

Vous pouvez faire cette imbrication de grilles autant que vous le souhaitez. Je ne pense pas vraiment à cela comme une imbrication puisque nous ne créons pas de tables imbriquées ici, et nous utilisons généralement les éléments HTML structurels déjà en place. Nous modifions simplement la valeur de display un niveau à la fois pour ce qui est le plus approprié pour les enfants de cet élément. Il peut s'agir d'une mise en page flexible ou d'une mise en page en grille, mais le plus souvent, il s'agira d'une mise en page en bloc et en ligne. Dans ce cas, nous n'avons rien à faire car c'est ce qui se passe par défaut.

Alignement des en-têtes et pieds de page

Comme nous l'avons vu, si nous voulons un ensemble de cartes disposées sur une grille, et que nous voulons qu'elles s'affichent aussi hautes que la carte la plus haute, et que nous voulons que les pieds de page soient poussés vers le bas de la carte, nous avons besoin de très peu de CSS . La mise en page CSS pour l'exemple ci-dessus est la suivante :

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; } article { display: grid; grid-template-rows: auto 1fr auto; row-gap: 20px; }

Et si nous voulons que la couleur d'arrière-plan des en-têtes et des pieds de page soit alignée ? Chaque carte est un élément de grille, mais les en-têtes et pieds de page se trouvent dans la grille de l'élément. Ils n'ont aucun lien entre eux et nous ne pouvons donc pas les aligner. Ici, ce serait bien si nous pouvions en quelque sorte hériter de la grille à travers les enfants.

Si nous pouvions définir une grille sur le parent qui avait trois lignes, placez les cartes sur ces trois lignes et placez l'en-tête, le contenu et le pied de page chacun dans l'une des lignes. De cette façon, chaque en-tête serait dans la même rangée, et donc si un en-tête devenait plus grand, toute la rangée deviendrait plus grande.

Nous n'avons pas de bonne solution à cela dans les navigateurs d'aujourd'hui, mais c'est en route. La fonctionnalité de sous-grille de CSS Grid Layout Level 2 activera ce modèle exact. Vous pourrez créer une grille sur le parent, puis choisir sélectivement les lignes et/ou les colonnes pour utiliser cette grille, plutôt que de définir une nouvelle grille sur l'élément child qui est complètement indépendant de cette grille.

Notez que les exemples qui suivent ne fonctionnent qu'au moment de la rédaction dans Firefox Nightly. La valeur de sous -grille de grid-template-columns et grid-template-rows est une nouvelle fonctionnalité et fait partie du niveau 2 de la spécification de grille CSS. Pour essayer cette fonctionnalité, téléchargez une copie de Firefox Nightly.

Vous pouvez voir comment cela fonctionne dans les images ci-dessous. Dans la première image, j'ai créé trois pistes de ligne sur le parent et étendu la carte sur elles. Avec l'inspecteur de grille de Firefox mettant en surbrillance la grille, vous pouvez voir que les lignes du parent ne sont pas liées aux lignes utilisées par les enfants.

Une image d'une grille à trois colonnes avec les pistes Firefox Grid Inspector superposées.
L'inspection de la grille avec Firefox Grid Inspector montre que les éléments ne s'affichent pas dans les pistes du parent. ( Grand aperçu )

Si, au lieu de définir trois lignes sur l'enfant, j'utilise la valeur subgrid pour grid-template-rows , la carte utilise maintenant ces lignes sur le parent. Vous pouvez voir comment les deux sont maintenant alignés et donc les en-têtes et les pieds de page s'alignent également :

Une image d'une grille à trois colonnes, tous les éléments à l'intérieur des cartes alignés.
En utilisant la sous-grille, chaque partie de la carte entre dans sa propre piste ( Grand aperçu )

Ce que nous faisons ici avec subgrid n'est pas une nouvelle valeur de display . L'élément qui est une sous-grille est un conteneur de grille lui-même, car nous y avons défini display: grid . Les éléments de la grille se comportent comme les éléments de la grille le font normalement. Il s'agit d'une disposition de grille régulière - pas différente de la grille imbriquée d'origine sauf que (au lieu que l'élément ait sa propre taille de piste de ligne), il utilise les pistes du parent.

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: repeat(2,auto 1fr auto); } article { grid-row-end: span 3; display: grid; grid-template-rows: subgrid; }

C'est la bonne chose à propos du sous-réseau ; il n'y a pas grand-chose à apprendre si vous savez déjà comment utiliser la disposition en grille. Vous pouvez lire le reste des détails dans mon article précédent ici sur Smashing Magazine, "CSS Grid Level 2: Here Comes Subgrid".

Hier (23 mai 2019), subgrid a atterri dans Firefox Nightly, nous avons donc une implémentation testable de la valeur subgrid de grid-template-columns et grid-template-rows . S'il vous plaît, prenez une copie de Nightly et essayez-le. Avec une copie de Nightly, vous pouvez voir l'exemple final fonctionner dans ce CodePen :

Voir l'affichage du stylet : la sous-grille n'est pas ce que nous voulons par Rachel Andrew.

Voir l'affichage du stylet : la sous-grille n'est pas ce que nous voulons par Rachel Andrew.

Voyez si vous pouvez imaginer d'autres cas d'utilisation qui sont résolus en ayant la fonctionnalité de sous-réseau, ou peut-être des choses qui, selon vous, manquent. Bien qu'une fonctionnalité ne soit disponible que dans un navigateur Nightly, c'est le moment où il est possible d'apporter des modifications à la spécification si un problème est découvert. Alors, rendez service à votre futur développeur Web et essayez des fonctionnalités comme celle-ci afin de contribuer à la plate-forme Web et d'améliorer les choses.

Si vous pensez avoir trouvé un bogue dans l'implémentation de Firefox, vous pouvez consulter le principal bogue d'implémentation sur Bugzilla qui renvoie à des problèmes connexes dans la section Dépend de . Si vous ne voyez pas votre problème, créez un cas de test aussi simple que possible et signalez le bogue. Si vous pensez que la sous-grille devrait faire quelque chose pour résoudre un cas d'utilisation, et que ce n'est pas détaillé dans la spécification, vous pouvez soulever un problème sur le groupe de travail CSS GitHub pour une amélioration potentielle.

Qu'en est-il de display: contents ?

Si vous avez suivi, vous pourriez penser que display: contents (comme décrit dans l'article précédent sur display ) pourrait résoudre les problèmes que subgrid cherche à résoudre - celui de permettre aux enfants indirects de participer à une disposition de grille. Ce n'est pas le cas, et notre exemple de cartes est un moyen parfait de démontrer la différence.

Si, au lieu de faire de notre carte une disposition en grille avec display: grid , nous supprimions la boîte en utilisant display: contents , nous obtiendrions ce résultat dans ce prochain CodePen. (Essayez de supprimer la ligne display: contents des règles pour .card pour voir la différence.)

Voir l'affichage du stylet : la sous-grille n'est pas ce que nous voulons par Rachel Andrew.

Voir l'affichage du stylet : la sous-grille n'est pas ce que nous voulons par Rachel Andrew.

Dans cet exemple, la boîte de la carte a été supprimée et l'en-tête, le contenu et le pied de page participent directement à la mise en page de la grille et sont placés automatiquement sur la grille. Ce n'était pas du tout ce que nous voulions ! La valeur du contents de l'affichage sera vraiment utile une fois que les problèmes d'accessibilité dans les navigateurs mentionnés dans mon dernier article seront traités, cependant, cela résout des problèmes différents de celui que nous explorons.

Plus de lecture et d'exemples

J'ai créé un certain nombre d'exemples et de démonstrations pour aider tout le monde à comprendre le sous-réseau. Vous pouvez les essayer sur les liens ci-dessous :

  • Exemples de grille CSS de niveau 2
  • Grille CSS niveau 2 : voici la sous-grille
  • Grilles jusqu'en bas (Présentation)
  • Documentation MDN pour le sous-réseau