CSS メーソンリーの代替案

公開日: 2024 年 4 月 30 日、最終更新日: 2026 年 2 月 13 日

Chrome チームは、ウェブでのレンガ積みレイアウトの実装を強く望んでいます。しかし、最近の WebKit の投稿で提案されているように、CSS Grid 仕様の一部として実装するのは誤りだと考えています。また、WebKit の投稿は、誰も提案していないバージョンの masonry に反対しているようにも感じられます。

そこで、この投稿では、Chrome が CSS Grid Layout 仕様の一部として masonry を実装することに懸念を抱いている理由を説明し、代替案で何が可能になるのかを明確にすることを目的としています。要するに、

  • Chrome チームは、メーソンリーのブロック解除に非常に熱心に取り組んでいます。これはデベロッパーが望んでいることだと認識しています。
  • 組積造をグリッド仕様に追加することは、組積造がグリッドかどうかという問題とは別の理由で問題があります。
  • グリッド仕様の外で masonry を定義しても、masonry の複数のトラック サイズや、配置やギャップなどのプロパティの使用、グリッド レイアウトで使用されるその他の機能の使用が妨げられることはありません。

グリッドに masonry を含めるべきですか?

Chrome チームは、masonry は display: masonry(または、より適切な名前が決定された場合は別のキーワード)を使用して定義される別のレイアウト メソッドであるべきだと考えています。この記事の後半で、コードでどのように表現できるかの例を示します。

グリッド レイアウトの外でメイソンリーを定義する方がよいと考える理由は 2 つあります。レイアウトのパフォーマンスの問題が発生する可能性があることと、メイソンリーとグリッドの両方に、一方のレイアウト方法では意味があるものの、もう一方のレイアウト方法では意味がない機能があることです。

パフォーマンス

グリッドと masonry は、ブラウザがサイズと配置を処理する方法が異なります。グリッドがレイアウトされると、すべてのアイテムがレイアウトの前に配置され、ブラウザは各トラックの内容を正確に把握します。これにより、グリッドで非常に便利な複雑な固有サイズ設定が可能になります。Masonry では、アイテムはレイアウトされたとおりに配置され、ブラウザは各トラックにいくつあるかを知りません。これは、すべての固有サイズのトラックやすべての固定サイズのトラックで発生する問題ではなく、固定サイズのトラックと固有サイズのトラックを組み合わせた場合に発生します。この問題を回避するために、ブラウザはすべてのアイテムを可能な限りすべての方法でレイアウトして測定値を取得するプリレイアウト ステップを実行する必要があります。大きなグリッドでは、これがレイアウト パフォーマンスの問題の原因となります。

そのため、grid-template-columns: 200px auto 200px のトラック定義を持つ masonry レイアウト(グリッドでよく行われること)がある場合、問題が発生し始めます。サブグリッドを追加すると、これらの問題は指数関数的に増加します

ほとんどのユーザーはこのような状況に遭遇しないという意見もありますが、非常に大きなグリッドを使用しているユーザーがいることはすでにわかっています。代替手段がある場合に、使用方法に制限があるものをリリースしたくありません。

各レイアウト方法で意味をなさないものについてはどうすればよいですか?

flexbox と grid が CSS の一部になったとき、開発者はそれらの動作に一貫性がないと感じることがよくありました。この不整合は、ブロック レイアウトに基づくレイアウトの仕組みに関する長年の仮定が原因でした。時間の経過とともに、デベロッパーはフォーマット コンテキストを理解し始めました。グリッドまたはフレックスの書式設定コンテキストに切り替えると、動作が異なるものがあります。たとえば、flexbox は 1 次元であるため、flexbox ではすべてのアライメント メソッドが使用できないことがわかっています。

masonry をグリッドにバンドルすると、フォーマット コンテキストと、Box Alignment 仕様でフォーマット コンテキストごとに定義されている配置プロパティなどの利用可能性との間の明確なリンクが壊れます。

前述のパフォーマンスの問題に対処するために、マトリックスで混合の固有トラックと固定トラックの定義を禁止することになった場合、グリッド レイアウトの一般的なパターンがマトリックスでは機能しないことを覚えておく必要があります。

また、grid-template-columns: repeat(auto-fill, max-content) のように、クロス制約がないため masonry では意味があるものの、グリッドでは無効のままにする必要があるパターンもあります。以下は、動作が異なる、または有効な値が異なるプロパティのリストです。

  • grid-template-areas: masonry では、masonry ではない方向の最初の行のみを指定できます。
  • grid-template: 短縮形はすべての違いを考慮する必要があります。
  • 有効な値の違いにより、grid-template-columnsgrid-template-rows のサイズ変更値をトラッキングします。
  • grid-auto-flow は masonry に適用されず、masonry-auto-flow は grid に適用されません。それらをマージすると、レイアウト方法が原因で無効になるという問題が発生します。
  • グリッドには 4 つの配置プロパティ(grid-column-start など)がありますが、Masonry には 2 つしかありません。
  • Grid では justify-*align-* の 6 つのプロパティをすべて使用できますが、Masonry では flexbox のようにサブセットのみを使用します。

また、デベロッパーが grid-with-masonry または grid-without-masonry で有効でない値を使用した場合に発生するすべての新しいエラーケースで、何が起こるかを指定する必要もあります。たとえば、grid-template-columns: masonry または grid-template-rows: masonry を使用することはできますが、両方を同時に使用することはできません。両方を同時に使用するとどうなりますか?すべてのブラウザが同じ動作をするように、これらの詳細を指定する必要があります。

仕様の観点から見ると、現在も将来も、すべてが複雑になります。すべてが masonry を考慮し、masonry で動作するかどうかを確認する必要があります。また、デベロッパーの視点から見ても混乱を招く可能性があります。display: grid を使用しているにもかかわらず、Masonry を使用しているために一部の機能が動作しないことを覚えておく必要があるのはなぜですか?

代替案

すでに述べたように、Chrome チームはグリッド仕様の外部で masonry を定義したいと考えています。これは、列のサイズが同じである非常にシンプルなレイアウト方法に限定されるという意味ではありません。WebKit の投稿にあるデモはすべて引き続き可能です。

従来の石積みレイアウト

多くの人が、レンガ積みというと、同じサイズの複数の列で構成されたレイアウトを思い浮かべます。これは、次の CSS を使用して定義されます。この CSS は、同等のグリッド バンドル バージョンよりもコード行数が少なくなっています。

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

同じサイズのトラック。

グリッドタイプのトラック サイズを使用して列の幅を調整する

前述の固有トラックと固定トラックのサイズ設定が混在している問題を除き、グリッドで気に入ったトラックのサイズ設定をすべて使用できます。WebKit のブログ投稿の例のように、狭い列と広い列が繰り返されるパターンです。

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

幅広と幅狭のトラックが交互に並んだパターン。

Masonry の追加のトラック サイズ設定

グリッドは 2 次元レイアウト手法であるため、グリッドでは使用できないトラック サイズ設定オプションが他にもあります。これらは masonry では便利ですが、grid で機能しないと混乱を招く可能性があります。

max-content サイズのトラックの自動入力。

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

auto サイズのトラックを自動入力すると、同じサイズのトラックが作成され、最大のトラックに合わせて自動サイズ調整されます。

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

自動サイズ調整トラックを使用した Masonry。

コンテンツが列をまたぐことを許可し、アイテムを Masonry レイアウトに配置する

コンテンツが列にまたがることを別の masonry 仕様で禁止する理由はありません。これは masonry-track プロパティを使用する可能性があります。これは、組積造レイアウトでスパンするディメンションが 1 つしかないため、masonry-track-startmasonry-track-end の省略形です。

.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 */
}

配置されたアイテムとスパンされたアイテムを含む Masonry。

サブマトリックスまたはマトリックス トラックを採用するサブグリッド

これは、別の masonry 仕様でサポートできます。ただし、固有サイズと固定サイズのトラックの混在は禁止されます。その具体的な内容は定義する必要があります。この方法が機能しない理由はありません。

まとめ

相互運用可能な仕様に到達したいと考えています。ただし、現在と将来にわたってうまく機能し、デベロッパーが信頼できる方法で実現したいと考えています。前述のパフォーマンスの問題に対処する唯一の方法は、2 つ目の問題(masonry でグリッドの一部が不正になる)を悪化させることです。特に、グリッドのすべての機能を維持しながら、異なるものを明確に分離できる場合は、それが良い解決策だとは思いません。

フィードバックがある場合は、問題 9041 のディスカッションにご参加ください。

この投稿のレビューと、その元になったディスカッションにご協力いただいた Bramus、Tab Atkins-Bittner、Una Kravets、Ian Kilpatrick、Chris Harrelson に感謝します。