CSS Gridで「あるあるレイアウト崩れ」を完全解決|現場で使える実践テクニック

C
クリオ
Web制作ディレクター / フロントエンジニア

こんにちは!

今日は「CSS Gridでよくあるレイアウト崩れの原因と対処法」について解説します。

CSS Gridはめっちゃ便利やけど、トラップがいっぱい

僕も3年前、CSS Gridを導入し始めたときはほんま苦労しました。
「Flexboxよりシンプルやろ」って思ってたんですけど、実際に案件で使い始めたら、レイアウト崩れが多発。
特に複雑なレイアウトやレスポンシブ対応になると、予期しない動きをするんですよね。

最初の失敗は、デザイナーから渡されたマルチカラムレイアウトをgrid-template-columnsだけで頑張ろうとしたこと。
PC時は3カラム、タブレット時は2カラム、モバイル時は1カラムという感じで、メディアクエリを駆使すれば対応できると思ってました。
でも、実装してみたら想定外の余白が出たり、要素の高さが揃わなくなったり…本当に大変でした。

その経験から、「CSS Gridを使う前に、押さえておくべき仕組みを理解することの大切さ」を実感したんです。
今日は、その教訓も含めて、現場で本当によく発生するトラブルを3つ、具体的な解決方法とともに紹介しますね。

「グリッドが想定と違うサイズになる」問題の解決法

CSS Gridで一番よくあるのが、「グリッドのサイズが思ってたのと違う」という問題です。
特にgrid-template-columns: 1fr 1fr 1frみたいに、fr単位を使うときに起きやすいんですよ。

例えば、こんなコードを書いたとします:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 20px;
  padding: 20px;
}

一見、3等分されるはずなんですけど、実はこのコードにはトラップがあります。
gappaddingの値がfrの計算に含まれないので、実際にはグリッド幅が想定より小さくなっちゃうんです。
結果として、各カラムが若干狭くなって、デザインがずれてしまう。

ほんま、初心者の方が引っかかりやすいポイントなんですよね。
解決法は、box-sizing: border-boxをコンテナに指定したり、以下のようにminmax()関数を使うといいですよ:

.grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  padding: 20px;
}

minmax(0, 1fr)にすることで、最小値を0に明示的に設定して、frの計算がより正確になります。
または、width: 100%を明示的に指定するのもいい方法ですね。

他にもよくあるのが、グリッドアイテムが予想より大きくなってしまう件。
これは、アイテムのwidthmin-widthが親の幅を超えているのが原因なことが多いです。
その場合は、グリッドアイテムにmin-width: 0を指定するといいですよ。
そうすることで、アイテムがグリッドセルを超えないようになります。

自動配置で要素が予想外の位置に配置される件

CSS Gridって、自動配置が便利な反面、めっちゃ罠があるんです。
例えば、グリッドアイテムを個別にgrid-columngrid-rowで指定した場合、他の要素が予想と違う位置に配置されちゃうんですよ。

こんな状況、現場でよく見ます。
デザイナーが「このボックスはここ、このボックスはそこ」みたいに細かく指定してくるわけですよ。
それを実装するために、各アイテムにgrid-column: 2 / 3みたいに座標を指定したら、他のアイテムが思いもよらない場所に配置されちゃった、と。

これを防ぐには、grid-auto-flowプロパティを活用するといいです。
デフォルトはgrid-auto-flow: rowなんですけど、これをgrid-auto-flow: denseに変更すると、空いてるスペースを埋めるように配置されます。

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-flow: dense;
  gap: 20px;
}

ただし、denseを使うと視覚的な順序がHTMLの順序と異なる可能性があるので、アクセシビリティ的には注意が必要ですね。
僕の経験上、より確実な方法は、事前に「どの要素がどこに配置されるか」をきっちり計画してから実装することです。
グリッドテンプレート図を書いて、全要素の配置位置を明記しておくと、トラブルが激減しますよ。

レスポンシブ時にグリッドが崩れるときの対応

CSS Gridでめっちゃ悩まされるのが、レスポンシブ対応なんです。
メディアクエリでgrid-template-columnsを変更するときに、うっかり前の状態のgrid-column指定が残ってたせいで、レイアウトが崩れるってケース、現場で頻繁に見ます。

具体例を挙げると、こんな感じです。

/* PC版 */
.grid {
  grid-template-columns: repeat(4, 1fr);
}

.item:nth-child(1) {
  grid-column: 1 / 3; /* 1列目から2列目にまたがる */
}

/* タブレット版 */
@media (max-width: 768px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);