Chrome チームは、ウェブにマサリ型レイアウトを実装することを強く望んでいます。ただし、最近の WebKit の投稿で提案されているように、CSS グリッド仕様の一部として実装することは間違いであると考えています。また、WebKit の投稿では、誰も提案していないマサリバージョンに反対する主張がなされています。
そのため、この投稿では、CSS グリッド レイアウト仕様の一部としてマサリを導入することに Chrome が懸念を抱いている理由を説明し、代替案で実現できる内容を明確にします。要するに、
- Chrome チームは、マサリをブロック解除することに非常に熱心です。これはデベロッパーの要望に沿ったものです。
- グリッド仕様にマサモリを追加することは、マサモリがグリッドであるかどうかという理由以外にも問題があります。
- グリッド仕様外でマサニを定義しても、マサニの複数のトラックのサイズや、配置やギャップなどのプロパティ、グリッド レイアウトで使用されるその他の機能の使用を妨げることはありません。
マサモはグリッドの一部である必要がありますか?
Chrome チームは、マサリは display: masonry
(または適切な名前が決まったら別のキーワード)を使用して定義される別のレイアウト方法であるべきだと考えています。この記事の後半では、コードでどのように見えるかを示した例をいくつか紹介します。
マサニがグリッド レイアウトの外部で定義されるべき理由は、レイアウトのパフォーマンスに関する問題の可能性と、マサニとグリッドの両方に、一方のレイアウト方法では意味があるがもう一方では意味がない機能があるという 2 つに関連しています。
パフォーマンス
グリッドとマサリーは、ブラウザがサイズと配置を処理する方法が異なります。グリッドがレイアウトされると、すべてのアイテムがレイアウトの前に配置され、ブラウザは各トラックに何が含まれているかを正確に把握します。これにより、グリッドで非常に便利な複雑な組み込みサイズ設定が可能になります。マサモリーでは、アイテムはレイアウトされたとおりに配置され、ブラウザは各トラックに何個あるかを知りません。これは、すべてのイントリンシック サイズのトラックやすべての固定サイズのトラックに問題があるわけではなく、固定サイズのトラックとイントリンシック サイズのトラックが混在している場合に問題になります。この問題を回避するには、ブラウザは、測定を取得するために、すべてのアイテムを可能な限りレイアウトするレイアウト前のステップを行う必要があります。グリッドが大きい場合、レイアウトのパフォーマンスの問題につながります。
そのため、グリッドでよくある grid-template-columns: 200px auto 200px
のトラックの定義を持つマサニョ レイアウトを使用すると、問題が発生します。サブグリッドを追加すると、これらの問題は指数関数的に増加します。
ほとんどのユーザーはこれに遭遇しないという議論もありますが、ユーザーが非常に大きなグリッドを使用していることはすでにわかっています。代替のアプローチがある場合は、使用方法に制限のあるものをリリースしたくありません。
各レイアウト方法で意味をなさないものについてはどうすればよいですか?
flexbox と grid が CSS の一部になったとき、開発者はこれらの動作が不整合であると感じることが多いと報告していました。発生した不整合は、ブロック レイアウトに基づくレイアウトの仕組みに関する長年の仮定が原因でした。時間の経過とともに、デベロッパーはフォーマット コンテキストを理解し始めています。グリッドまたは Flex の書式設定コンテキストに切り替えると、動作が異なる場合があります。たとえば、flexbox は 1 次元であるため、flexbox ではすべての配置方法を使用できないことをご存じでしょう。
マサリをグリッドにまとめると、書式設定コンテキストと、書式設定コンテキストごとにボックスの配置仕様で定義されている配置プロパティなどの可用性との明確なリンクが切断されます。
マサリで組み込みトラックと固定トラックの定義を混在させることを禁止して、前述のパフォーマンスの問題に対処する場合は、グリッド レイアウトで非常に一般的なパターンがマサリでは機能しないことを覚えておく必要があります。
grid-template-columns: repeat(auto-fill, max-content)
など、マサジックに適したパターンもあります。これは、クロス制約がないものの、グリッドでは無効のままにする必要があるためです。以下は、動作が異なると予想されるプロパティ、または有効な値が異なるプロパティのリストです。
grid-template-areas
: マサニズムでは、マサニズム以外の方向の最初の行のみを指定できます。grid-template
: ショートカットでは、すべての違いを考慮する必要があります。- 有効な値が異なるため、
grid-template-columns
とgrid-template-rows
のサイズ設定値を追跡します。 grid-auto-flow
はマサリには適用されず、masonry-auto-flow
はグリッドには適用されません。これらを統合すると、使用しているレイアウト方法が原因で無効になる問題が発生します。- グリッドには 4 つのプレースメント プロパティ(
grid-column-start
など)がありますが、マソンリーには 2 つしかありません。 - グリッドでは
justify-*
とalign-*
の 6 つのプロパティをすべて使用できますが、Masonry では Flexbox などのサブセットのみを使用します。
また、デベロッパーがグリッド(マサモリあり)またはグリッド(マサモリなし)で有効でない値を使用したことにより発生する新しいエラーケースすべてで、どのような処理が行われるかを指定する必要があります。たとえば、grid-template-columns: masonry
または grid-template-rows: masonry
を使用することは有効ですが、両方を同時に使用することはできません。両方を同時に使用するとどうなりますか?すべてのブラウザで同じ動作をするように、これらの詳細を指定する必要があります。
これらはすべて、現在および将来、仕様の観点から複雑になります。すべてにおいて、マサリと、マサリで機能するかどうかを考慮する必要があります。開発者の視点からも混乱を招きます。display: grid
を使用しているにもかかわらず、マサリを使用しているために一部の機能が動作しないことを覚えておく必要があるのはなぜですか?
代替案
すでに説明したように、Chrome チームはグリッド仕様以外でマサリを定義したいと考えています。ただし、列サイズが同じ非常にシンプルなレイアウト方法に限定されるわけではありません。WebKit に関する投稿のデモはすべて引き続き可能です。
従来の石積みレイアウト
マサリと聞いて、ほとんどの人が思い浮かべるのは、同じサイズの複数の列があるレイアウトです。これは次の 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;
}
マサリ用トラックの追加サイズ
グリッドは 2 次元のレイアウト方法であるため、グリッドでは使用できないトラック サイズ設定オプションもあります。これらはマソンリーでは便利ですが、グリッドで機能しない場合、混乱を招く可能性があります。
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;
}
コンテンツを列にまたいで配置し、アイテムをマサリ レイアウトに配置する
別のマサリ仕様で列にまたがるコンテンツを指定しない理由はありません。マサリ レイアウトでは、要素をまたぐディメンションが 1 つしかないため、masonry-track-start
と masonry-track-end
の省略形である masonry-track
プロパティを使用できます。
.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 */
}
マソンリー トラックを採用したサブマソンリーまたはサブグリッド
これは、別のマサリ仕様でサポートできます。ただし、組み込みトラックと固定サイズのトラックが混在することはできません。具体的にはどのようなものかを定義する必要があります。これが機能しない理由は考えられません。
まとめ
相互運用性のある仕様をリリースできる段階に到達したいと考えています。ただし、Google は、現在と将来にわたって機能し、デベロッパーが信頼できる方法で、この取り組みを進めたいと考えています。上記のパフォーマンスの問題に対処する唯一の方法は、2 つ目の問題(グリッドの一部がマソンリーで無効である)を悪化させることです。特に、異なる要素を明確に分離しながら、必要なグリッド機能をすべて使用できる場合は、これは良いソリューションではありません。
フィードバックがある場合は、Issue 9041 のディスカッションに参加してください。
この投稿のレビューと、投稿の参考となったディスカッションに協力してくれた Bramus、Tab Atkins-Bittner、Una Kravets、Ian Kilpatrick、Chris Harrelson に感謝します。