a-blog cms のグループユニットでメイソンリー(Masonry)レイアウトを実現する方法

グループユニットに CSS クラスを付けるだけで、Pinterest 風の段組みレイアウトになる仕組みです。JavaScript は一切不要、CSS の columns だけで完結します。
はじめに
以前に書いた「グループユニットで Swiper を利用する方法」と同じ系統の小ネタです。あちらは JavaScript でユニットの中身をスライダーに組み替える方式でしたが、今回のメイソンリーは JavaScript を一切使いません。CSS の columns プロパティだけで、高さの異なる画像が隙間なく積み上がる「メイソンリー(Masonry)」レイアウトを実現します。
編集者がやることは、いつものグループユニットの 「CSSクラス」欄に masonry と入力するだけ。テンプレートの編集も、特別な JS の読み込みも要りません。今回も Claude Code に手伝ってもらいながら、あっという間に完成しました。備忘録として残しておきます。
何ができるようになるか
複数の画像ユニットを 高さバラバラのまま隙間なく 段組み表示できる
カラム数は画面幅に応じて自動で 4 → 3 → 2 → 1 に切り替わる(レスポンシブ)
JavaScript 不要なので 表示が速く、崩れにくい
クラス名を変えるだけで列数のバリエーション(
masonry-3/masonry-2)を使い分けられる
仕組みは「グループユニットに CSS クラスを付与 → そのクラスに対して CSS を当てる」というだけ。Swiper のときと同じ、a-blog cms のグループユニットを起点にした実装パターンです。
実装の全体像
① テーマに CSS を追加(masonry.css を作成)
↓
② head で読み込む(link タグを 1 行追加)
↓
③ 編集画面でグループユニットに masonry クラスを入力
制作者がやるのは ① と ②、編集者がやるのは ③ だけです。順に見ていきます。
1. テーマに CSS を読み込む
テーマの head 出力テンプレート(例:/include/head/link.html)に、後述の CSS ファイルを 1 行追加します。
<!-- Masonry(メイソンリー)グループユニット用スタイル -->
<link rel="stylesheet" href="/css/masonry.css">既存テーマであれば、PhotoCollage や Swiper のカスタム CSS を読み込んでいる行の近くに並べておくと管理しやすいです。
2. CSS
/css/masonry.css
ポイントは、グループユニットが <div class="column-group ここに入力したクラス"> という形で出力されることです。そのため CSS は .column-group.masonry のように指定します。
/* ===== メイソンリーレイアウト(グループユニット用) =====
使い方:グループユニットの「CSSクラス」欄に
masonry(4列)/ masonry-3(3列)/ masonry-2(2列)を入力するだけ。
方式:CSS の columns(multi-column)。JavaScript 不要。 */
.column-group.masonry,
.column-group.masonry-3,
.column-group.masonry-2 {
--masonry-gap: 16px; /* ユニット間の余白。ここだけ変えれば全体に効く */
column-gap: var(--masonry-gap);
}
.column-group.masonry { column-count: 4; } /* PC:4カラム */
.column-group.masonry-3 { column-count: 3; } /* 3カラム */
.column-group.masonry-2 { column-count: 2; } /* 2カラム */
/* グループ直下の各ユニットを、カラムをまたがず積む(最重要)。
縦の余白も --masonry-gap に揃える(横の column-gap と一致させる)。
テーマ標準の figure 余白(margin-block:0 32px・詳細度 0,2,1)に勝つため、
[role="figure"] を明示して詳細度を上げ、論理プロパティ margin-block で上書きする。 */
.column-group.masonry > *,
.column-group.masonry-3 > *,
.column-group.masonry-2 > *,
.column-group.masonry > [role="figure"],
.column-group.masonry-3 > [role="figure"],
.column-group.masonry-2 > [role="figure"] {
break-inside: avoid;
margin-block: 0 var(--masonry-gap);
}
/* a-blog cms の配置(左右寄せ)やサイズ指定をメイソンリー内では無効化し、
各ユニットをカラム幅にフィットさせる。 */
.column-group.masonry .column-media,
.column-group.masonry-3 .column-media,
.column-group.masonry-2 .column-media {
float: none;
width: 100%;
max-width: 100%;
margin-inline: 0;
}
/* サイズ指定ユニット(インライン width 指定の内側 div)も幅 100% に上書き */
.column-group.masonry .column-media > [style*="width"],
.column-group.masonry-3 .column-media > [style*="width"],
.column-group.masonry-2 .column-media > [style*="width"] {
width: 100% !important;
min-width: 0 !important;
}
/* 画像をカラム幅にフィット */
.column-group.masonry img,
.column-group.masonry-3 img,
.column-group.masonry-2 img {
display: block;
width: 100%;
height: auto;
}
/* レスポンシブ:画面幅でカラム数を段階的に減らす */
@media (max-width: 900px) {
.column-group.masonry { column-count: 3; }
.column-group.masonry-3 { column-count: 2; }
}
@media (max-width: 600px) {
.column-group.masonry { column-count: 2; }
.column-group.masonry-3 { column-count: 2; }
}
@media (max-width: 380px) {
.column-group.masonry,
.column-group.masonry-3,
.column-group.masonry-2 { column-count: 1; }
}ポイント:
break-inside: avoid;が最重要。これが無いと、1 つのユニットがカラムの境目で上下に分断されてレイアウトが崩れます。子セレクタ
.column-group.masonry > *で種別を問わず対応。画像・テキストなどユニットの種類に関わらず、グループ直下の要素すべてを段組み対象にできます。配置・サイズ指定の打ち消し。a-blog cms は画像ユニットに左右寄せ(float)や幅指定が付くことがあるため、メイソンリー内ではそれらをリセットしてカラム幅に揃えています。
縦横の余白を一致させる。a-blog cms の画像ユニット(
[role="figure"])にはテーマ標準でmargin-block(例:32px)が付きます。これが残ると 縦の余白だけ横より広く なるため、[role="figure"]を明示して詳細度で勝ち、縦余白も--masonry-gapに上書きして横(column-gap)と揃えています。
3. 管理画面での設定(編集者向け)
エントリー編集画面で、並べたい画像ユニットを追加していく
メイソンリーにしたい 複数のユニットを「グループユニット」でまとめる
グループユニットの設定で、「CSSクラス」欄に
masonryと入力(3 列にしたいときはmasonry-3、2 列はmasonry-2)保存して表示を確認
これだけで、グループ内のユニットが自動で段組みに並びます。
仕組みのポイント
項目 | 内容 |
|---|---|
| 親(グループユニット)に効き、子ユニットを自動で各カラムへ流し込む |
| ユニットがカラムの境目で分断されるのを防ぐ。これが無いと崩れる |
| 子セレクタにすることで、画像・テキストなどユニット種別を問わず対応 |
注意:並び順について
columns 方式は、要素が 上 → 下(縦方向) に流れます。1 段目から横並びに「1, 2, 3, 4」とは並ばず、縦に「1 → 2 → 3 …」と積まれていきます。写真ギャラリーのように 順序が厳密でない用途 に最適です。「左から順番どおりに」並べたい場合は、この方式は不向きです。
やってはいけないこと / 補足
display: gridのネイティブ Masonry(grid-template-rows: masonry等)は実運用に使わない。仕様が未確定で、ブラウザによって構文が異なり崩れるためです。グループユニットの 入れ子は避ける(カラム計算が複雑になり崩れやすい)。
余白やカラム数を変えたいときは、CSS 冒頭の
--masonry-gapとcolumn-countの値だけ調整すれば OK です。
まとめ
グループユニットの CSSクラス欄に
masonryと入れるだけで段組みになるCSS の
columns方式なので JavaScript 不要・高速・崩れにくいカギは
break-inside: avoidと、配置・サイズ指定の打ち消し
Swiper のときは JS でゴリゴリ組み替えていましたが、メイソンリーは CSS だけでここまでできてしまいます。グループユニットに「クラスを付けるだけ」で機能が増えていくのは、運用がラクで良いなと改めて思いました。次は別のレイアウトパターンも仕込んでみたいところです。