Autre proposition pour la maçonnerie CSS

L'équipe Chrome aimerait voir implémenter des mises en page de type maçonnerie sur le Web. Cependant, nous pensons que son implémentation dans le cadre de la spécification CSS Grid proposée dans la récente publication sur WebKit serait une erreur. Nous pensons également que l'article de WebKit a plaidé contre une version de maçonnerie que personne ne proposait.

Par conséquent, cet article vise à expliquer pourquoi Chrome se préoccupe de l'implémentation de maçonnerie dans le cadre de la spécification de mise en page en grille CSS, et de clarifier ce que la proposition alternative permet. En résumé :

  • L'équipe Chrome est très attachée à débloquer la maçonnerie, nous savons que c'est quelque chose que les développeurs veulent.
  • L'ajout de maçonnerie à la spécification de la grille pose problème pour d'autres raisons que de savoir si vous pensez que la maçonnerie est une grille ou non.
  • Définir le maçonnerie en dehors de la spécification de grille n'empêche pas l'utilisation de plusieurs tailles de voie pour la maçonnerie, ni l'utilisation de propriétés telles que l'alignement ou les espaces, ou de toute autre fonctionnalité utilisée dans la mise en page en grille.

La maçonnerie doit-elle faire partie de la grille ?

L'équipe Chrome pense que "maçonnerie" doit constituer une méthode de mise en page distincte, définie à l'aide de display: masonry (ou d'un autre mot clé si un nom plus approprié est disponible). Plus loin dans cet article, vous verrez quelques exemples de ce à quoi cela pourrait ressembler dans le code.

Nous pensons que la maçonnerie est mieux définie en dehors de la mise en page en grille pour deux raisons liées : le potentiel de problèmes de performances de mise en page, et le fait que la maçonnerie et la grille présentent des fonctionnalités pertinentes dans une méthode de mise en page, mais pas dans l'autre.

Performances

La grille et la maçonnerie sont opposées dans la façon dont le navigateur gère le dimensionnement et le placement. Lorsqu'une grille est mise en page, tous les éléments sont placés avant la mise en page, et le navigateur sait exactement ce qui se trouve dans chaque piste. Cela permet le dimensionnement intrinsèque complexe qui est si utile dans la grille. Avec la maçonnerie, les éléments sont placés tels qu'ils sont disposés, et le navigateur ne sait pas combien il y en a dans chaque piste. Ce n'est pas un problème avec toutes les pistes de taille intrinsèque ou de taille fixe, mais si vous mélangez des pistes fixes et intrinsèques. Pour résoudre le problème, le navigateur doit effectuer une étape de pré-mise en page consistant à mettre en page chaque élément de toutes les manières possibles afin d'obtenir des mesures, avec une grande grille, ce qui contribuerait aux problèmes de performances de mise en page.

Par conséquent, si vous disposez d'une mise en page en maçonnerie avec une définition de piste de grid-template-columns: 200px auto 200px (une opération très courante dans une grille), vous commencez à rencontrer des problèmes. Ces problèmes deviennent exponentiels lorsque vous ajoutez des sous-réseaux.

Il existe un argument selon lequel la plupart des gens ne seront pas confrontés à ce problème. Toutefois, nous savons déjà que les gens possèdent de très grands réseaux. Nous ne voulons pas proposer un produit qui impose des limites à son utilisation, alors qu'il existe une approche alternative.

Que faisons-nous des éléments qui n'ont pas de sens dans chaque méthode de mise en page ?

Lorsque les formats Flexbox et GR ont été intégrés au CSS, les développeurs ont souvent eu l'impression de se comporter de manière incohérente. L'incohérence qu'elle rencontrait était due à des hypothèses de longue date concernant le fonctionnement de la mise en page, basée sur la mise en page en blocs. Au fil du temps, les développeurs ont commencé à comprendre le formatage des contextes. Lorsque nous passons dans un contexte de mise en forme flexible ou de grille, certaines choses se comportent différemment. Par exemple, vous savez que lorsque vous utilisez Flexbox, toutes les méthodes d'alignement ne sont pas disponibles, car cette technologie est unidimensionnelle.

Le regroupement de la maçonnerie dans une grille rompt ce lien clair entre le contexte de mise en forme et la disponibilité d'éléments tels que les propriétés d'alignement, définies dans la spécification Box Alignment par contexte de mise en forme.

Si nous décidons de résoudre le problème de performances décrit précédemment en rendant illégales les définitions mixtes de voie intrinsèque et fixe dans la maçonnerie, vous devrez garder à l'esprit qu'un modèle très courant de mise en page en grille ne fonctionne pas pour la maçonnerie.

Il existe également des modèles adaptés à la maçonnerie, par exemple grid-template-columns: repeat(auto-fill, max-content), car vous n'avez pas de contraintes croisées, mais vous devez rester non valide dans la grille. Voici une liste de propriétés pour lesquelles nous prévoyons un comportement différent ou des valeurs valides différentes.

  • grid-template-areas: dans un maçonnerie, vous ne pouvez spécifier la première ligne que dans le sens non maçonnerie.
  • grid-template: le raccourci doit tenir compte de toutes les différences.
  • Suivez les valeurs de taille pour grid-template-columns et grid-template-rows en raison de différences au niveau des valeurs légales.
  • grid-auto-flow ne s'applique pas à la maçonnerie et masonry-auto-flow ne s'applique pas à la grille. Leur fusion créerait des problèmes pour des éléments non valides en raison de la méthode de mise en page utilisée.
  • La grille possède quatre propriétés d'emplacement (grid-column-start, etc.), tandis que la maçonnerie n'en a que deux.
  • La grille peut utiliser les six propriétés justify-* et align-*, mais Masonry n'utilise qu'un sous-ensemble comme Flexbox.

Vous devrez également spécifier ce qui se passe dans tous les nouveaux cas d'erreur causés par les développeurs qui utilisent une valeur non valide dans une grille avec maçonnerie ou une grille sans maçonnerie. Par exemple, vous pouvez utiliser grid-template-columns: masonry ou grid-template-rows: masonry, mais pas les deux à la fois. Que se passe-t-il si vous utilisez les deux en même temps ? Ces informations doivent être spécifiées pour que tous les navigateurs effectuent la même action.

Tout cela se complique du point de vue des spécifications, aujourd'hui et à l'avenir. Nous devrons nous assurer que tout tient compte de la maçonnerie, et qu'elle fonctionne ou non dans la maçonnerie. C'est également déroutant du point de vue des développeurs. Pourquoi est-il nécessaire de garder dans la tête que, malgré l'utilisation de display: grid, certaines choses ne fonctionnent pas du fait de l'utilisation de maçonnerie ?

Une autre proposition

Comme indiqué précédemment, l'équipe Chrome souhaite définir la maçonnerie en dehors de la spécification de la grille. Cela ne signifie pas qu'il serait limité à une méthode de mise en page très simple avec des tailles de colonne identiques. Toutes les démos dans la publication de WebKit resteront possibles.

Disposition classique en maçonnerie

Lorsque la plupart des gens pensent à la maçonnerie, ils pensent à une mise en page avec plusieurs colonnes de taille égale. Elle doit être définie à l'aide du code CSS suivant, qui nécessite un code inférieur à celui de la version équivalente groupée (grille).

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

Des pistes de taille égale.

Utiliser le dimensionnement des pistes en type grille pour différentes largeurs de colonne

Outre le problème mentionné précédemment concernant la taille mixte des pistes intrinsèques et fixes, vous pouvez utiliser toutes les tailles de piste que vous aimez à partir de la grille. Comme dans l'exemple de l'article de blog WebKit, qui consiste à répéter des colonnes étroites et plus larges.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

Motif composé de pistes larges et étroites.

Dimensionnement supplémentaire des rails pour la maçonnerie

Il existe d'autres options de dimensionnement de piste que nous n'autorisons pas dans la grille, car il s'agit d'une méthode de mise en page à deux dimensions. Ceux-ci seraient utiles en maçonnerie, mais cela serait déroutant s'ils ne fonctionnaient pas en grille.

Saisie automatique de titres de taille max-content.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

Remplissage automatique de pistes de taille auto, ce qui crée des pistes de même taille et s'ajuste automatiquement pour accueillir la plus grande.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

Maçonnerie avec rails dimensionnés automatiquement

Autoriser le contenu à s'étendre sur plusieurs colonnes et placer des éléments en maçonnerie

Il n'y a aucune raison de ne pas avoir de contenu couvrant des colonnes dans une spécification de maçonnerie distincte. Cela peut utiliser une propriété masonry-track, qui est un raccourci pour masonry-track-start et masonry-track-end, car vous n'avez qu'une seule dimension pour couvrir les éléments dans une mise en page en maçonnerie.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

Maçonnerie avec des éléments encastrés et enveloppants.

Sous-maçonnerie ou sous-grille adoptant des rails de maçonnerie

Cela peut être pris en charge avec une spécification de maçonnerie distincte, à nouveau, à condition que les voies mixtes et de taille fixe ne soient pas autorisées. Vous devez définir exactement ce à quoi cela ressemble. Nous ne voyons aucune raison pour laquelle cela ne fonctionnerait pas.

Conclusion

Nous aimerions arriver à un point de spécification pouvant être expédié de manière interopérable. Cependant, nous souhaitons que cela fonctionne bien aujourd'hui et à l'avenir, et sur lequel les développeurs peuvent s'appuyer. La seule façon de traiter les problèmes de performances décrits serait d'aggraver le deuxième problème, à savoir le fait que certaines parties du réseau sont illégales dans la maçonnerie. Nous ne pensons pas que ce soit une bonne solution, en particulier lorsqu'il est possible d'avoir toutes les caractéristiques de grille souhaitées tout en conservant les éléments différents clairement séparés.

Si vous avez des commentaires, participez à la discussion sur le problème 9041.

Merci à Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick et Chris Harrelson pour avoir examiné cet article et les discussions qui l'ont éclairé.