なぜジグザグレイアウトなのか
通常のグリッドレイアウトはすべてのアイテムが整然と並びますが、時にはアイテムが滝のように斜めに流れるリズミカルなレイアウトが必要になることがあります。このようなデザインはCSS Gridとtransformの組み合わせでスマートに実現できます。
Flexboxでも似たような効果は出せますが、flex-direction: column + flex-wrap: wrap方式は固定高さが必要で、タブオーダーが崩れるという致命的な欠点があります。アイテムが視覚的に1→2→3→4と流れても、実際のDOM順序は縦方向に先に埋まるため、アクセシビリティに問題が生じます。Gridアプローチではこの問題を完全に回避できます。

コアコード: CSS Grid + translateY(50%)の組み合わせ
/* 基本リセットとボックスモデルの統一 */
*, *::before, *::after {
box-sizing: border-box;
}
.wrapper {
--gap: 16px; /* 間隔を変数で管理 */
--item-height: 100px; /* アイテムの高さ(ハードコード必須) */
display: grid;
grid-template-columns: 1fr 1fr; /* 2カラムグリッド */
gap: var(--gap);
max-width: 800px;
margin: 0 auto;
/* 変換されたアイテムがはみ出さないようパディングを確保 */
padding-bottom: calc(var(--item-height) / 2 + var(--gap) / 2);
}
.item {
height: var(--item-height);
border: 2px solid;
}
/* 偶数番目のアイテムのみ50% + 間隔の半分だけ下に移動 */
.item:nth-child(even of .item) {
transform: translateY(calc(50% + var(--gap) / 2));
}
💡 セレクタのTips:
.item:nth-of-type(even)でも可能ですが、nth-of-typeはタグ名を基準に動作します。.wrapper内にdiv.itemとspan.itemが混在していると意図しない結果になります。:nth-child(even of .item)はクラス名で正確にフィルタリングするため、より安全です。

transformパーセントの秘密: 自分自身基準
CSSの他のプロパティ(例: width: 50%)は親要素のサイズを基準にします。しかしtransform: translateY(50%)は自分自身の高さを基準に移動します。アイテムの高さが100pxなら50px下に移動します。
この特性のおかげで、アイテムの高さが変わっても比率が維持されます。もしアイテムの高さが200pxならtranslateY(50%)は100px移動するため、ジグザグの間隔が自動調整されます。
🚨 Overflow問題と解決法
transformは視覚効果に過ぎず、実際のレイアウトには影響しません。そのため、偶数アイテムが下に移動しても親の.wrapperは元の位置を基準に高さを計算するため、アイテムがコンテナからはみ出します。
解決策はpadding-bottomを追加して事前にスペースを確保することです。パディングの値は(アイテム高さ / 2) + (gap / 2)で計算します。この値はCSS変数で管理するとメンテナンスが容易です。

まとめ: ジグザグレイアウトの3つのポイント
- 2カラムCSS Gridが基本骨格を提供します。
translateY(50%)がジグザグ効果を生み出し、transformパーセントが自分自身基準である点が鍵です。padding-bottomでoverflowを防ぐ必要があります。
技術の限界と注意点
--item-heightをハードコードする必要があるため、コンテンツに応じて高さが変わる環境では不向きです。transformはGPUアクセラレーションを受けますが、大量のアイテム(100個以上)で使用するとパフォーマンスに影響が出る可能性があります。- スクリーンリーダーはDOM順序に従うため、視覚的な順序とDOM順序が異なると混乱を招きます。この方法では視覚的順序とDOM順序が一致するため安全です。
次のステップとしての学習方向
- CSS
container queriesを使ったレスポンシブなジグザグレイアウト prefers-reduced-motionを考慮したエントリーアニメーションの追加subgridを活用したより複雑な非対称グリッドパターン
参考資料: 元記事 CSS-Tricks