CSS gapの使い方?Flexboxでレスポンシブ?効かないときは? / いがわ

.

Memo

gapの使い方。対応ブラウザとflexboxでレスポンシブ。

gapとは?

CSS gapプロパティ。
gapという選択肢。

divなどで作ったボックスを並べるとき、要素間に均一な余白を開けると綺麗に見える。

これまでは「margin」、もしくは「padding」を使うのが一般的だったが、「gap」を使うという選択肢が増えた。

対応ブラウザ。

すでにモダンブラウザはgapに対応している。

参考: gap” | Can I use… Support tables for HTML5, CSS3, etc

gapの使い方の例。flexboxでレスポンシブ。効かないときの画像。

gapの指定方法。

marginやpaddingなどと同様に、一括指定と分割指定がある。

一括指定の例。「gap
  • gap: 10px 20px;
  • gap: 10px;
分割指定の例。「row-gap」と「column-gap
  • row-gap: 10px;
    column-gap: 20px;
  • row-gap: 10px;
    column-gap: 10px;
gapのプロパティと値の形式。
gap: row-gap column-gap;
  • gap: row-gap column-gap; といった形式となる。
  • gap: 10px 20px; の場合。最初の値が横方向(row / 行と行の間隔)、2番目の値が縦方向(column / 列と列の間隔)。)
  • gapの指定は親要素へ行う。効かないときのチェックポイントの1つ。)

参照:gap (grid-gap) – CSS: カスケーディングスタイルシート | MDN

gapで行と列の一括指定。

つまり、「gap」は「row-gap」と「column-gap」を一括指定するプロパティ。

  • row(行)は横方向。
  • column(列)は縦方向。
行列。
行と列の覚え方の例。

行(row)と列(column)は、どっちがどっちだったかを忘れやすい。

なので例えば下記のように、「行列」の漢字の形からの覚え方がある。

gap使用時の注意。行列(rowとcolumn)の図解。
Row。
Rowの覚え方の例。

また、ロンドンの通りの「Savile Row(サヴィル・ロウ)」や、Bod Dylanの曲の「Desolation Row(邦題:廃墟の街)」など、「row」には「通り」や「街並み」と言った意味がある。

ちょっと変わった感じの覚え方かもだが、「row」は横方向、というイメージを持てる。

css gap rowのイメージ。


CSSボックスモデル。

gapとボックスモデル。
ボックスモデル。

gapを使う前に、ある程度CSSのボックスモデルを理解しておいた方が後々無難。

CSSでレイアウトを組む際に、「width」や「height」などの計算が必要となるため、これを怠ると、レイアウト崩れの原因となってしまう。

例えば、

2カラムにしたい場合。

親要素に、

  • display: flex;
  • flex-wrap: wrap;

子要素に、

  • width: 50%; もしくは、width: calc(100% / 2);

などといった指定をする。

問題点。

これは、内側の余白(padding)やボーダー(border)が必要ない箇所では問題ない。

ただし、「padding」や「border」が必要な箇所では、途端に計算がややこしくなる。

「padding」や「border」の値の分、ボックスの範囲が広がることを頭に入れておかなければならない。

ついついこれを忘れてしまうと、すぐにレイアウトが大変なことになってしまう。

box-sizing プロパティ。
CSSボックスモデル。

そこで便利なのが、「box-sizing」プロパティ。これを利用すると計算がしやすくなる。

box-sizing: content-box;の場合。

「width」の値に、「padding」と「border」を含めない。

CSSボックスモデルの図解。

box-sizing: border-box;の場合。

「width」の値に、「padding」と「border」を含める。

参照:box-sizing – CSS: カスケーディングスタイルシート | MDN


box-sizing: content-box;
「padding」と「border」を含めない。

「box-sizing」の初期値は「content-box」であり、この場合は「width」や「height」の値に「padding」と「border」を含めない。

box-sizing: border-box;
「padding」と「border」を含める。

「box-sizing」を「border-box」にすると、「width」や「height」の値に「border」と「padding」を含める。

gapで作る間隔のイメージ。


gapの使い方。marginやpaddingとの違いと、実装例。

gapの実装例。

以下の内容を元に実装。

  • ボックスサイズは「border-box」。
  • ボックスレイアウトは「Flexbox」。
  • 親要素のボックスの横幅は「100%」。
  • 子要素は4カラムになるように「(100% / 4)」。
  • 子要素の縦幅は「100px」。
  • ボックスモデルを表現するために、子要素に「border: 10px solid #bbb;」を指定。

marginを使った場合。

  • marginは、borderの外側の余白となる。
  • 子要素の間隔は、「margin: 1%;」で指定。
  • widthにmarginが含まれないので、marginの分を引く。
  • :last-childなどの擬似クラスを使わなくても、きっちり収められる。
結果。

content

content

content

content

content

content

content

content

HTML
<div class="post">
 <div class="flex box_01">
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
 </div><!--flex box_01-->
</div><!--post-->
CSS
.post .flex {
 display: flex;
 width: 100%;
 justify-content: flex-start;
 flex-wrap: wrap;
 background: #ccc;
 box-sizing: border-box;
}
.post .flex div {
 height: 100px;
 background: #999;
 box-sizing: border-box;
}
.post .flex div p {
 display: flex;
 align-items: center;
 justify-content: center;
 width: 100%;
 height: 100%;
 background: transparent;
 margin: 0;
 padding: 0;
 color: #fff;
 font-weight: bold;
}

.post .flex.box_01 div {
 width: calc((100% / 4) - 2%); /* 4分割して、marginの値を引く。 */
 margin: 1%; /* marginを使って間隔を調整。 */
 border: 10px solid #bbb;
}

paddingを使った場合。

  • paddingは、borderを含んだ内側の余白となる。
  • 子要素の間隔は、「padding: 1%;」で指定。
  • widthにpaddingが含まれるので、paddingの分を引く必要はない。
  • :last-childなどの擬似クラスを使わなくても、きっちり収められる。
結果。

content

content

content

content

content

content

content

content

HTML
<div class="post">
 <div class="flex box_02">
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
 </div><!--flex box_02-->
</div><!--post-->
CSS
.post .flex {
 display: flex;
 width: 100%;
 justify-content: flex-start;
 flex-wrap: wrap;
 background: #ccc;
 box-sizing: border-box;
}
.post .flex div {
 height: 100px;
 background: #999;
 box-sizing: border-box;
}
.post .flex div p {
 display: flex;
 align-items: center;
 justify-content: center;
 width: 100%;
 height: 100%;
 background: transparent;
 margin: 0;
 padding: 0;
 color: #fff;
 font-weight: bold;
}

.post .flex.box_02 div {
 width: calc(100% / 4); /* 4分割のみで、paddingの値は引かない。 */
 padding: 1%; /* paddingを使って間隔を調整。 */
 border: 10px solid #bbb;
}

gapを使った場合。

  • gapは、marginやpaddingと違い、親要素へ指定する。効かないときのチェックポイント。)
  • gapは、単位を%で指定すると、row-gapの余白が効かない。効かないときのチェックポイント。)
  • 4カラムにしたかったが、今回のコードではカラム落ちをした。(「width」の計算がmarginやpaddingと違ってややこしい。box-sizingが意味をなさない。)
結果。

content

content

content

content

content

content

content

content

HTML
<div class="post">
 <div class="flex box_03">
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
 </div><!--flex box_03-->
</div><!--post-->
CSS
.post .flex {
 display: flex;
 width: 100%;
 justify-content: flex-start;
 flex-wrap: wrap;
 background: #ccc;
 box-sizing: border-box;
}
.post .flex div {
 height: 100px;
 background: #999;
 box-sizing: border-box;
}
.post .flex div p {
 display: flex;
 align-items: center;
 justify-content: center;
 width: 100%;
 height: 100%;
 background: transparent;
 margin: 0;
 padding: 0;
 color: #fff;
 font-weight: bold;
}

.post .flex.box_03 {
 gap: 1%; /* gapを使って間隔を調整。 */
}
.post .flex.box_03 div {
 width: calc(100% / 4);
 border: 10px solid #bbb;
}

gapを使った場合。(row-gapの単位をpxで。)

  • 単位を「%」ではなく「px」で指定すると、row-gapの余白が効く。
  • rowの値なので、当然これだけでは4カラムにはならない。(「width」の計算がややこしい。)
結果。

content

content

content

content

content

content

content

content

HTML
<div class="post">
 <div class="flex box_04">
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
  <div>
   <p>content</p>
  </div>
 </div><!--flex box_04-->
</div><!--post-->
CSS
.post .flex {
 display: flex;
 width: 100%;
 justify-content: flex-start;
 flex-wrap: wrap;
 background: #ccc;
 box-sizing: border-box;
}
.post .flex div {
 height: 100px;
 background: #999;
 box-sizing: border-box;
}
.post .flex div p {
 display: flex;
 align-items: center;
 justify-content: center;
 width: 100%;
 height: 100%;
 background: transparent;
 margin: 0;
 padding: 0;
 color: #fff;
 font-weight: bold;
}

.post .flex.box_04 {
 gap: 10px; /* row-gapの単位にpxを使って間隔を調整。column-gapの値もrow-gapに合わせる。 */
}
.post .flex.box_04 div {
 width: calc(100% / 4);
 border: 10px solid #bbb;
}


gapについての結論。

flexとは相性が良くない。

上記のようにカラム落ちが起こるため、Flexboxには向いていないと感じた。

(カラム落ちなんてIE6以来。)

「gap」は比較的新しいプロパティのため、その前にリリースされていた「box-sizing」では考慮されていない。

ボックスのwidthやheightの計算方法が、marginやpaddingと違う。)

gridとは相性が良い。

gridレイアウトにしたり、単位を「px」で指定すると「gap」は良いかもしれない。

ボックス内のコンテンツを等間隔に配置することは、「margin」でも「padding」でも「gap」でも、どれを使用しても可能だ。

なので、自分の環境やチーム内でやりやすいプロパティでレイアウトを組めば良いのではないだろうか。

あくまでも優先すべきなのは、

  • ユーザーファースト。
  • SEO対策。
  • コーディング方法の効率化。
  • チームワークでの統一。

ということの方が望ましいと思われる。

サイトを見るユーザーやGooglebotは、どのプロパティであろうが、気にすることはない。

flexboxのgapについて考える猫の画像。

以上、参考になれば幸いです。


Webデザインは実務数年、職業訓練校講師数年、フリーランス数年、計15年以上のキャリアがありますが、一気にがぁっと書いているので「です・ます調」ではありません。(元々はメモ書きでした。) 事実や経験、調査や検証を基にしていますが、万一なにかしら不備・不足などがありましたらすみません。お知らせいただければ訂正いたします。 写真は主にUnsplashPixabayのフリー素材を利用させていただいております。その他の写真や動画もフリー素材やパブリックドメイン、もしくは自前のものを使用しております。

井川 宜久 / Norihisa Igawa
デザイナー、ディレクター、講師、コーチ / 井川宜久

CSS 関連メモ。


免責事項について

  • 記事ページ(Memosのページ)は当初は文字通りメモ書きでした。その後、修正や更新をしております。
  • 事実や経験、調査や検証を基にしていますが、万一なにかしら不備・不足などがありましたらすみません。お知らせいただければ早急に対応いたします。
  • 一個人のポートフォリオサイトですので、万一損害・トラブル等が発生した場合でも、一切の責任を負いかねます。