CSSのみで実装するMasonryレイアウト



主に画像などのコンテンツをギャラリーとして見せていく場合によく利用されるグリッドレイアウト。格子状に分割してブロック内に要素を配置するなかで、各要素はブロックごとで決められたサイズとなりますが、要素の内容によってバラバラのサイズのレイアウトにしたいこともあります。

画像のギャラリー表示のデザインでは、ブロック積みのような組積造レイアウトを構築していくことになるでしょう。

そのようなデザインを実装するには、これまでJavaScriptのライブラリを利用する必要がありましたが、今後はCSSのみで、行と列のトラックサイズを指定するgrid-templateプロパティを利用することでも実装が可能となります。

ただ、まだ試験段階でありますので、今後期待されるプロパティの動作になります。
Webブラウザのサポート状況は、以下で確認できます。

Can I use (grid-template masonry)
https://caniuse.com/?search=grid-template%20masonry

2022年11月現在では、Firefoxにて設定エディター(about:configページ) で「layout.css.grid-template-masonry-value.enabled」の項目を「true」として、設定を有効にすることで確認ができます。

また、Appleデバイスに標準で搭載されているWebブラウザで、2023年秋頃にリリースされるSafari 17からサポートされます。現在は、いち早く新機能を試せる開発向けのSafariブラウザ「Safari Technology Preview」で確認することができます。

Safari Technology Preview
https://developer.apple.com/safari/technology-preview/

CSSのみで実装するMasonry Grid Layout


実装方法をサンプルを交えてご紹介します。
画像ギャラリーとなると、imgタグまたはキャプションを含むことができるfigureタグを使っていくことでしょう。
2つのパターンで見ていきます。

<img> tag


imgタグを使った構造をHTMLで構築します。
画像を覆う親要素には、CSSクラス「gallery」を付与しておきます。

HTML

<section class="gallery">
  <img src="images/sample01.jpg" alt="sample01">
  <img src="images/sample02.jpg" alt="sample02">
  <img src="images/sample03.jpg" alt="sample03">
  <img src="images/sample04.jpg" alt="sample04">
  <img src="images/sample05.jpg" alt="sample05">
  <img src="images/sample06.jpg" alt="sample06">
  <img src="images/sample07.jpg" alt="sample07">
  <img src="images/sample08.jpg" alt="sample08">
  <img src="images/sample09.jpg" alt="sample09">
  <img src="images/sample10.jpg" alt="sample10">
</section>



用意する画像は、アスペクト比(縦横比)がバラバラのものでOKです。

続いてCSS。
親要素のCSSクラス「gallery」にグリッドレイアウトのスタイルを指定していきます。

CSS

body {
  background-color: #333;
}

.gallery {
  max-width: 1280px;
  margin: auto;
  padding: 8px;
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  grid-template-rows: masonry;
}



画像を覆う親要素のCSSクラス「gallery」に、「display: grid;」と指定してグリッドコンテナとします。
「gap: 8px;」でグリッドアイテムの余白は8pxとしています。
グリッドアイテム横並びの実装は、列トラックの大きさを指定するgrid-template-columnsプロパティで、repeat関数やminmax関数、min関数を使いながら、レスポンシブWebデザインに適応するように指定しています。

そして、行トラックの大きさを指定するgrid-template-rowsプロパティに、pxやem、frといったサイズ単位ではなく「masonry」と指定します。

もし、行トラックの大きさを指定していない場合は、以下のように一番大きいサイズの高さでグリッドレイアウトを形成します。

Grid Layoutの画像の横並び



grid-template-rowsプロパティで「masonry」を指定することで、空いているスペースを埋めるように組積造レイアウトを形成することができます。

CSSのみで実装するMasonryレイアウトの画像ギャラリー

<figure> tag


ギャラリーコンテンツの説明であったり、リンクなどの選択要素があるのであれば、figureタグを使っていくことでしょう。

例えば、以下のようなHTML構造を作ります。
figure要素内にimg要素の画像とfigcaption要素のキャプションを。そしてキャプションにはaタグでリンクを貼ります。

HTML

<section class="gallery">
  <figure>
    <img src="images/sample01.jpg" alt="sample01">
    <figcaption><a href="#">1. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample02.jpg" alt="sample02">
    <figcaption><a href="#">2. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample03.jpg" alt="sample03">
    <figcaption><a href="#">3. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample04.jpg" alt="sample04">
    <figcaption><a href="#">4. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample05.jpg" alt="sample05">
    <figcaption><a href="#">5. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample06.jpg" alt="sample06">
    <figcaption><a href="#">6. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample07.jpg" alt="sample07">
    <figcaption><a href="#">7. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample08.jpg" alt="sample08">
    <figcaption><a href="#">8. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample09.jpg" alt="sample09">
    <figcaption><a href="#">9. Caption</a></figcaption>
  </figure>
  <figure>
    <img src="images/sample10.jpg" alt="sample10">
    <figcaption><a href="#">10. Caption</a></figcaption>
  </figure>
</section>



CSSでは先ほどのスタイルのほか、figure要素内のスタイルを、grid-rowプロパティやgrid-columnプロパティを使って指定しています。
そして、親要素のCSSクラス「gallery」も先ほど同様、grid-template-rowsプロパティを「masonry」と指定します。

CSS

body {
  background-color: #333;
}

.gallery {
  max-width: 1280px;
  margin: auto;
  padding: 8px;
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  grid-template-rows: masonry;
}

.gallery figure {
  display: grid;
  grid-template-rows: 1fr auto;
}

.gallery img {
  grid-row: 1 / -1;
  grid-column: 1;
}

.gallery figcaption {
  grid-row: 2;
  grid-column: 1;
  background-color: rgba(255, 255, 255, .7);
  max-width: 90%;
  margin: 0 0 .4rem;
  padding: .2rem .6rem;
  justify-self: center;
}

.gallery figcaption a {
  color: #333;
  text-decoration: none;
}



Masonry LayoutがサポートされていないWebブラウザでは、キャプションもずれるのでうまく調整する必要がでてきたりしますが、Masonry Layoutがサポートされていれば、綺麗に組積造レイアウトでデザインしていくことができます。

CSSのみで実装するMasonryレイアウトの画像ギャラリー(figureタグとキャプション)



以下、ここまでの実装になります。
動画(3分30秒ほど)

まとめ


Webブラウザのサポートが進んでこれば、JavaScriptを利用することなくレンガ組積のような組積造レイアウトを実装することができるでしょう。

今回は画像ギャラリーのサンプルで見てきましたが、テキストを含むブロックコンテンツでも利用することができます。
今後のレイアウトの構築方法として知っておくと良いでしょう。