LoginSignup
66
36

More than 1 year has passed since last update.

CSSだけでMasonryレイアウト

Last updated at Posted at 2022-08-21

この記事の概要

Pinterestに代表されるMasonryレイアウト、実現したいと思ったことはありませんか?

このレイアウトを、CSSだけで実現する方法を書きました。

この記事を投稿している2022年8月17日現在、基本的にすべてのブラウザで利用不可です。
そのため、これは未来に向けた記事投稿です。
なお、Firefoxのみabout:configからlayout.css.grid-template-masonry-value.enabledにすることで試すことができます。

基本的な書き方

以下のようなHTMLに対してスタイルを当てる前提で進めます。

<div class="grid">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

まず、Masonryを適用したい領域にdisplay: grid;を適用します。

  .grid {
    display: grid;
  }

次に、grid-template-columnsまたはgrid-template-rowsのどちらかにmasonryを指定します。
grid-template-columnsであれば水平方向の、grid-template-rowsであれば垂直方向の空白を埋めるようにして配置されます。
以下の例では(使う頻度の多いであろう)grid-template-rowsを採用しました。

  .grid {
    display: grid;
+   grid-template-rows: masonry;
  }

最も簡単な書き方で言えば、上記で完了です。
あとはgapbackground-colorなど、見た目を整えるためのコードを追加するのみです。

See the Pen Untitled by Keisuke Watanuki (@xrxoxcxox) on CodePen.

配置の仕組み

実態は詳細なアルゴリズムによって決定されるのですが、人間がざっくり理解するための説明を記載します。

ずばり「最も余白のある列(または行)に次々と要素を配置する」です。

先ほどのCodePenでの例をもとに説明します。
まず、1番目の要素を配置する際は、まだ1つも要素がないので通常のCSS Gridと同じ仕組みで配置されます。
今回で言えば左上です。

次に、2から4番目の要素です。
例ではgrid-template-columns: repeat(4, 1fr);という指定をしているため、4列描画されることは確定です。
そのため4番目までの要素は左から順に詰めて配置されます。

5番目の要素を配置します。
1から4列目を見ると、最も余白が大きいのは1列目です。
そのため、5番目の要素は1列目に配置されます。

5番目の要素の配置により、最も余白が大きいのは3列目となりました。
そのため6番目の要素は3列目に配置されます。

6番目の要素を配置してもなお、最も余白が大きいのは3列目です。
そのため、7番目の要素も3列目に配置されます。

残りの、8から10番目の要素は、ここまでの流れに沿って配置されるのみです。

ときには「あくまでHTMLの記載順通りに配置して欲しい」と思うかもしれません。
その場合はmasonry-auto-flow: next;を指定すると良いでしょう。
こちらを指定すると、あくまでグリッド順に沿って順番に要素が配置されるようになります。

応用的な書き方

先ほどの例でいうと、.itemクラスのついた要素にgrid-column-start: span 2;などを指定し幅を変えたり、grid-column: 2 / 4;などを指定して位置を固定したりもできます。

通常のdisplay: grid;と同様に、明確な配置指定をもつ要素はそうでない要素よりも優先的に配置されるので、先ほど説明した流れからは少し変わります。

また、align-contentのような役割を果たすalign-tracksjustify-tracksというプロパティも存在します。
取りうる値もalign-contentと同じなのですが、カンマ区切りで複数指定して、それぞれの列(または行)に個別で設定が可能です。

参考


最後まで読んでくださってありがとうございます!
Twitterでも情報を発信しているので、良かったらフォローお願いします!

66
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
66
36