Comment définir la mise en page en maçonnerie CSS ?

Ian Kilpatrick
Ian Kilpatrick
Tab Atkins-Bittner
Tab Atkins-Bittner

Publié le 19 septembre 2024

Le groupe de travail CSS a combiné les deux propositions de mise en page en maçonnerie CSS dans une esquisse de spécification. Le groupe espère que cela facilitera la comparaison des deux et la prise de décision finale. L'équipe Chrome pense toujours qu'une syntaxe de maçonnerie distincte est la meilleure solution. Bien que le plus gros problème de performances mentionné dans notre précédent post soit résolu, des questions subsistent concernant la syntaxe, les valeurs initiales et la facilité d'apprentissage d'une version combinée à une grille.

Toutefois, pour tester nos hypothèses, nous avons travaillé sur quelques exemples pour montrer comment la maçonnerie fonctionnerait avec chaque version. Consultez les exemples de ce post et faites-nous part de vos commentaires afin que nous puissions prendre une décision et mettre en place cette fonctionnalité.

Cet article ne couvre pas tous les cas d'utilisation possibles, mais il est clair que la séparation de la mise en page en maçonnerie de la mise en page en grille ne signifie pas que la fonctionnalité manque de fonctionnalités. En fait, l'inverse peut être vrai. Comme vous le verrez dans cet article, la version display: masonry offre de nouvelles opportunités et une syntaxe plus simple. De plus, de nombreux développeurs ont exprimé des inquiétudes concernant le fait que le réordonnancement d'éléments avec une mise en page en maçonnerie puisse entraîner des problèmes d'accessibilité. Ce problème est également résolu pour les deux versions de la syntaxe, via la propriété reading-flow proposée.

Mise en page de base en maçonnerie

C'est la mise en page que la plupart des gens imaginent lorsqu'ils pensent à la maçonnerie. Les éléments s'affichent en lignes. Une fois la première ligne placée, les éléments suivants se déplacent dans l'espace laissé par les éléments plus courts.

Mise en page avec des colonnes, les éléments remplissant les colonnes sans espace.
Dans cette mise en page, les colonnes sont définies, puis les éléments sont remplis par maçonnerie plutôt que par lignes strictes.

Avec display: masonry

Pour créer une mise en page en maçonnerie, utilisez la valeur masonry pour la propriété display. Cela crée une mise en page en maçonnerie avec des canaux de colonnes que vous définissez (ou qui sont définis par le contenu) et une mise en maçonnerie dans l'autre axe. Le premier élément s'affiche au début du bloc et en ligne (donc en haut à gauche), et les éléments sont disposés dans la direction en ligne.

Pour définir des pistes, utilisez masonry-template-tracks avec des valeurs de liste de pistes telles qu'elles sont utilisées dans la mise en page en grille CSS.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(3, 1fr);
  gap: 10px;
}

Avec display: grid

Pour créer une mise en page en maçonnerie, commencez par créer une mise en page en grille à l'aide de la valeur grid pour la propriété display. Définissez des colonnes avec la propriété grid-template-columns, puis attribuez à grid-template-rows la valeur masonry.

Une mise en page sera créée, comme vous pouvez vous y attendre avec les éléments de grille placés automatiquement. Toutefois, les éléments de chaque ligne utilisent une mise en page en maçonnerie et se réorganiseront pour occuper l'espace laissé par les éléments plus petits de la ligne précédente.

.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry;
  gap: 10px;
}

Points à prendre en compte entre les deux options

Une différence notable entre ces méthodes est que, avec la version display: masonry, vous obtenez une mise en page en maçonnerie même si vous ne spécifiez aucun canal avec masonry-template-tracks. Par conséquent, display: masonry peut suffire. En effet, la valeur initiale de masonry-template-tracks est repeat(auto-areas, auto). La mise en page crée autant de pistes à taille automatique que possible dans le conteneur.

Flux inversé avec maçonnerie

La spécification inclut des méthodes permettant de modifier la direction du flux de maçonnerie. Par exemple, vous pouvez modifier le flux à afficher à partir de l'extrémité du bloc.

Mise en page avec des colonnes, les éléments qui remplissent les colonnes le font à partir du bas de la mise en page.
Dans cette mise en page, les colonnes sont définies, puis les éléments sont remplis par maçonnerie en commençant par la fin du bloc.

Avec display: masonry

Créez une mise en page en maçonnerie avec display: masonry, puis utilisez masonry-direction avec une valeur de column-reverse.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(3, 1fr);
  masonry-direction: column-reverse;
}

Avec display: grid

Créez une mise en page en maçonnerie avec display: grid et grid-template-rows: masonry. Utilisez ensuite la propriété grid-auto-flow avec une nouvelle valeur de row-reverse pour que les éléments soient mis en page à partir de l'extrémité du bloc du conteneur de grille.

.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry;
  grid-auto-flow: row-reverse;
}

Points à prendre en compte entre les deux options

La version display: masonry ressemble beaucoup au fonctionnement de Flexbox. Modifiez le sens de flux des colonnes à l'aide de la propriété masonry-direction avec une valeur de column-reverse.

La version de la grille CSS utilise grid-auto-flow. Comme défini actuellement, grid-auto-flow: row-reverse et grid-auto-flow: column-reverse auraient le même effet. Cela peut prêter à confusion, car vous vous attendez peut-être à ce qu'il fasse autre chose.

Disposition en maçonnerie pour les lignes

Vous pouvez également changer de direction pour définir des lignes.

Mise en page avec des lignes, les éléments remplissant les lignes sans espace.
Dans cette mise en page, les lignes sont définies, puis les éléments sont remplis par une mise en page en maçonnerie plutôt que par des colonnes strictes.

Avec display: masonry

Créez une mise en page en maçonnerie avec display: masonry, puis définissez la valeur de masonry-direction sur row. Sauf si vous souhaitez que vos lignes aient une taille de bloc spécifique, vous n'avez pas besoin de spécifier de taille de piste, car la valeur par défaut est auto. Les pistes seront donc dimensionnées en fonction du contenu qu'elles contiennent.

.masonry {
  display: masonry;
  masonry-direction: row;
}

Avec display: grid

.masonry {
  display: grid;
  grid-template-columns: masonry;
  grid-template-rows: repeat(3, 1fr);
}

Points à prendre en compte entre les deux options

Comme pour le flux inversé, si vous passez de la version display: masonry en colonnes à la version en lignes, vous devez modifier la valeur de masonry-direction. Avec la version de la grille, vous devrez échanger les valeurs des propriétés grid-template-columns et grid-template-rows. Ou, si vous utilisez l'abréviation, modifiez l'ordre de la syntaxe.

Dans ces deux exemples de flux de commutation, la version display: masonry semble plus intuitive. Il n'existe qu'une seule propriété qui contrôle le flux masonry-direction. Elle prend l'une des valeurs suivantes:

  • row
  • column
  • row-reverse
  • column-reverse

Vous ajoutez ensuite toutes les informations de dimensionnement nécessaires à masonry-template-tracks, en supposant que la valeur automatique par défaut ne vous convient pas.

Avec la grille, pour inverser l'orientation, vous devez utiliser la propriété grid-auto-flow. Pour effectuer la maçonnerie en ligne, modifiez la valeur des propriétés grid-template-*. Dans la syntaxe de grille actuelle, il n'est pas non plus possible de laisser la valeur de l'axe de la grille non définie. Vous devez toujours spécifier des propriétés grid-template-* sur l'axe qui n'a pas de valeur masonry.

Positionner des éléments

Dans les deux versions, vous pouvez positionner explicitement des éléments à l'aide de l'emplacement basé sur les lignes que vous connaissez déjà de la mise en page en grille. Dans les deux versions, vous ne pouvez positionner des éléments que sur l'axe de la grille, c'est-à-dire l'axe avec les canaux prédéfinis. Vous ne pouvez pas positionner d'éléments sur l'axe qui effectue la mise en page en maçonnerie.

Avec display: masonry

Le code CSS suivant définit une mise en page en maçonnerie avec quatre colonnes. L'axe de la grille est donc les colonnes. L'élément de classe a est placé de la première ligne de colonne à la troisième ligne de colonne, couvrant deux canaux avec les nouvelles propriétés masonry-track-*. Cela peut également être défini comme un raccourci de masonry-track: 1 / 3;.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(4, 1fr);
}

.a {
  masonry-track-start: 1;
  masonry-track-end: 3;
}

Avec display: grid

Le code CSS suivant définit une mise en page en maçonnerie avec quatre colonnes. L'axe de la grille est donc les colonnes. L'élément de classe a est placé de la première ligne de colonne à la troisième ligne de colonne, couvrant deux canaux avec les propriétés grid-column-*. Vous pouvez également définir cette valeur comme raccourci de grid-column: 1 / 3;.

Si l'axe de la grille est les colonnes, les propriétés grid-row-* sont ignorées. Si l'axe de la grille est les lignes, les propriétés grid-columns-* sont ignorées.

.masonry {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

.a {
  grid-column-start: 1;
  grid-column-end: 3;
}

Vous pouvez utiliser des lignes nommées avec les deux syntaxes. Les exemples suivants montrent une grille avec deux lignes de colonnes nommées a.

Avec display: masonry

Les lignes nommées sont définies dans la valeur de la liste des pistes de masonry-template-tracks. L'élément peut être placé après n'importe quelle ligne nommée a.

.masonry {
  display: masonry;
  masonry-template-tracks: 100px [a] auto [a] auto 100px;
}

.item {
  masonry-track: a;
}

Avec display: grid

Les lignes nommées sont définies dans la valeur de la liste des pistes de grid-template-columns. L'élément est placé après la première ligne nommée a. Si la propriété grid-row est définie, elle sera ignorée.

.masonry {
  display: grid;
  grid-template-columns: 100px [a] auto [a] auto 100px;
  grid-template-rows: masonry;
}

.item {
  grid-column: a;
  grid-row: a; /* ignored */
}

Vous pouvez également utiliser des zones nommées dans les deux syntaxes. Les exemples suivants montrent une grille avec trois canaux nommés "a", "b" et "c".

Avec display: masonry

Les pistes sont nommées en fonction de la valeur de masonry-template-areas. Étant donné qu'aucune taille de piste n'est définie, les trois sont définies par défaut sur la taille auto. L'élément est placé dans le canal "a".

.masonry {
  display: masonry;
  masonry-template-areas: "a b c";
}

.item {
  masonry-track: a;
}

Le fonctionnement est le même que vous définissiez des lignes ou des colonnes. La seule différence concerne la propriété masonry-direction.

Avec display: grid

Pour les colonnes, la syntaxe est essentiellement identique. De même, comme aucune taille de canal n'est définie, les trois sont définies par défaut sur la taille auto, mais vous devez toujours indiquer explicitement que l'autre axe est en maçonnerie:

.masonry {
  display: grid;
  grid-template-areas: "a b c";
  grid-template-rows: masonry;
}

.item {
  grid-column: a;
}

Toutefois, pour les lignes, la valeur doit être écrite différemment, car grid-template-areas définit en fait une zone bidimensionnelle, et chaque ligne est écrite sous forme de chaîne distincte:

.masonry {
  display: grid;
  grid-template-areas: "a" "b" "c"; /* Note the difference, each row is quoted. */
  grid-template-columns: masonry;
}

.item {
  grid-row: a;
}

Points à prendre en compte entre les deux options

Avec n'importe quel positionnement, la syntaxe display: masonry fonctionne mieux pour changer de direction. Comme la propriété masonry-track-* fonctionne dans la direction de l'axe de la grille, il vous suffit de modifier la valeur de masonry-direction pour changer de direction. Avec la version de la grille, vous aurez au moins besoin de propriétés redondantes pour activer le basculement. Consultez toutefois les exemples précédents pour découvrir d'autres façons dont le changement de direction est plus compliqué avec la version de la grille.

Raccourcis

Dans cet article, les notations longues ont été utilisées pour indiquer plus clairement les propriétés utilisées. Toutefois, les versions display: masonry et display: grid peuvent être définies à l'aide d'abréviations.

Avec display: masonry

Le raccourci display: masonry utilise le mot clé masonry. Pour créer la mise en page de maçonnerie de base, utilisez le code CSS suivant:

.masonry {
  display: masonry;
  masonry: repeat(3, 1fr);
}

Pour créer une mise en page en maçonnerie simple basée sur des lignes:

.masonry {
  display: masonry;
  masonry: row;
}

Pour définir des canaux et une mise en page basée sur les lignes à l'aide de la syntaxe abrégée:

.masonry {
  display: masonry;
  masonry: repeat(3, 1fr) row;
}

Avec display: grid

Pour créer la mise en page de maçonnerie de base à l'aide de la syntaxe abrégée grid.

.masonry {
  display: grid;
  grid: masonry / repeat(3, 1fr);
}

Pour créer une mise en page en maçonnerie simple basée sur des lignes:

.masonry {
  display: grid;
  grid: repeat(3, auto) / masonry;
}

Dans des exemples plus complexes, comme la syntaxe globale de display:masonry est plus simple, vous pouvez regrouper davantage de propriétés dans l'abréviation sans qu'elle ne devienne trop complexe.

Par exemple, imaginez que vous créez trois colonnes nommées "a", "b" et "c", remplies de bas en haut.

Avec display:masonry

Dans display: masonry, vous pouvez définir ces trois éléments ensemble à l'aide de la forme abrégée:

.masonry {
  display: masonry;
  masonry: column-reverse "a b c";
}

Étant donné qu'elles sont redimensionnées automatiquement, vous n'avez pas besoin de spécifier les tailles. Toutefois, si vous souhaitez ajouter une taille spécifique, vous pouvez le faire. Exemple : masonry: column-reverse 50px 100px 200px "a b c";.

De plus, chaque composant peut être réorganisé librement. Il n'y a pas d'ordre spécifique à retenir. Si vous souhaitez plutôt effectuer des lignes, il vous suffit de remplacer column-reverse par row ou row-reverse. Le reste de la syntaxe reste inchangé.

Avec display: grid

Dans display: grid, ces trois aspects doivent être définis séparément:

.masonry {
  display: grid;
  grid-template-rows: masonry;
  grid-template-areas: "a b c";
  grid-auto-flow: wrap-reverse;
}

Comme dans l'exemple de maçonnerie, toutes les colonnes ont la taille auto, mais si vous souhaitez fournir des tailles explicites, vous pouvez le faire:

.masonry {
  display: grid;
  grid: masonry / 50px 100px 200px;
  grid-template-areas: "a b c";
  grid-auto-flow: wrap-reverse;
}

Si vous souhaitez utiliser "grille" pour définir les tailles et les noms des zones en même temps:

.masonry {
  display: grid;
  grid: "a b c" masonry / 50px 100px 200px;
  grid-auto-flow: wrap-reverse;
}

Dans ces deux exemples, l'ordre est strictement obligatoire et différent si vous souhaitez plutôt des lignes. Par exemple, pour passer aux lignes, procédez comme suit:

.masonry {
  display: grid;
  grid: 50px 100px 200px / masonry;
  grid-template-areas: "a" "b" "c";
}

Pour les regrouper tous dans une seule abréviation:

.masonry {
  display: grid;
  grid: "a" 50px "b" 100px "c"  200px / masonry;
}

Points à prendre en compte entre les deux options

L'abréviation display: masonry est susceptible d'être largement utilisée, car il s'agit d'une abréviation relativement simple. Dans de nombreux cas, pour une mise en page "standard" en maçonnerie, vous n'avez qu'à définir les définitions de canaux. Toutes les autres valeurs peuvent utiliser la valeur par défaut.

La version display: grid utilise l'abréviation grid existante, qui est une abréviation assez complexe et qui, d'après notre expérience, est moins fréquemment utilisée par les développeurs. Comme indiqué dans les exemples précédents, même lorsqu'il est utilisé pour des mises en page de maçonnerie simples, il faut faire attention lorsque vous définissez l'ordre des valeurs.

Autres points à noter

Cet article examine certains cas d'utilisation courants aujourd'hui, mais nous ne savons pas ce que l'avenir nous réserve pour la grille ou la maçonnerie. L'utilisation de la syntaxe display: masonry distincte est justifiée par le fait qu'elle permet de les faire diverger à l'avenir. En particulier, avec les valeurs initiales (telles que celles pour masonry-template-tracks), il peut être utile de faire quelque chose de différent dans la maçonnerie que dans la grille. Nous ne pouvons pas modifier les valeurs par défaut de la grille si nous optons pour la version display: grid, ce qui pourrait limiter les actions que nous pourrions vouloir effectuer à l'avenir.

Dans ces exemples, vous pouvez voir les endroits où le navigateur doit ignorer les propriétés valides dans la grille si vous utilisez la mise en page en maçonnerie. Par exemple, grid-template-areas, où la plupart des valeurs sont supprimées, car il définit une mise en page en grille bidimensionnelle. Dans la maçonnerie, nous ne définissons qu'une seule direction.

Envoyer vos commentaires

Consultez ces exemples, ainsi que la version provisoire de la spécification qui présente chaque version à côté de l'autre. N'hésitez pas à nous faire part de votre avis en commentant le problème 9041. Si vous préférez rédiger un post sur votre propre blog ou sur les réseaux sociaux, n'oubliez pas de nous en informer sur X ou LinkedIn.