yasuda

縦の余白を考慮したレスポンシブなグリッドシステム

Bootstrapのようなグリッドシステムは便利ですが、コンテンツ内で使おうとすると困ってしまう場面があります。

例えばスマホでは1カラムでPCでは2カラムにしたい場合です。

PCの時は横並びになったカラムの間に余白(ガター)が入るので問題ないですが、

2カラムのグリッドのレイアウト例

スマホの時に縦に並んだカラムの間に余白が入らないので要素が詰まってしまいます。

1カラムのグリッドで余白がつかないことを示した図

スタイルガイドを使った案件ではグリッドを使ってレイアウトを整えることも多いですが、レスポンシブで余白をコントロールしようとすると、既存のグリッドシステムだけでは足りないこともあります。

今回紹介するのは、上記の問題を解消したコンテンツ内でも使えるオリジナルのグリッドシステムです。
デモと実際のソースコードは以下のURLから確認できます。

マークアップ

HTMLは以下のようになります。親要素にクラスを付け替えることでバリエーションを出していきます。

<ul class="st-Grids st-Grids-col2 st-Grids-col3Md">
  <li class="st-Grids_Item">…</li>
  <li class="st-Grids_Item">…</li>
</ul>

上記では、スマホは2カラムで、md幅(例えばタブレット)からは3カラムにするという指定です。

命名規則はECSSをベースにしていますが、適宜変更してください。

ベースのスタイル

今回のグリッドはinline-blockを使用しています。floatと違ってclear: both;を指定する必要がないのでスタイルの管理が簡単になるのと、垂直位置の変更ができたりするのでよく使っています。flexboxが使える案件であれば変更してもいいと思います。

余白の指定は使い回すので変数化しておきます。

// `em`と`%`は指定不可
$st-grids-column-gap: 15px;
$st-grids-row-gap: 15px;
$st-grids-column-gap-md: 30px;
$st-grids-row-gap-md: 30px;

$st-grids-column-gapは左右の余白、$st-grids-row-gapは上下の余白です。それぞれ-mdとしているのはメディアクエリのキーワードです。-pcのように考えてもらえれば大丈夫です。
以下の記事で詳しく説明しています。

Sassの変数とmixinで変更に強いメディアクエリをつくる

グリッドのベーススタイルです。

メディアクエリをmixin化していない場合は、@include mq-up(md)@media print, screen and (min-width: 768px)のように書き換えてください。

.st-Grids {
  margin-left: -$st-grids-column-gap;
  padding-left: 0;
  list-style-type: none;
  display: block;
  font-size: 0;

  @include mq-up(md) {
    margin-left: -$st-grids-column-gap-md;
  }

  /* 同じ階層にある`.st-Grids`同士の間に余白を入れます。 */
  &:not(:first-of-type) {
    margin-top: $st-grids-row-gap;

    @include mq-up(md) {
      margin-top: $st-grids-row-gap-md;
    }
  }
}

.st-Grids_Item {
  display: inline-block;
  width: 100%;
  padding-left: $st-grids-column-gap;
  font-size: medium;
  font-size: 1rem;
  vertical-align: top;

  @include mq-up(md) {
    padding-left: $st-grids-column-gap-md;
  }
}

グリッドの親要素が同階層に並んだ時に余白をつけたいので指定しています。

&:not(:first-of-type) {
  margin-top: $st-grids-row-gap;

  @include mq-up(md) {
    margin-top: $st-grids-row-gap-md;
  }
}

レスポンシブのスタイル

レスポンシブのスタイルは1カラムと2カラム、均等でないカラムの3パターンを紹介します。

1カラム

.st-Grids_Item {
  &:nth-of-type(n+2) {
    margin-top: $st-grids-row-gap;
  }
}

1カラムの時にはカラムの間に上下の余白をつけたいので、2つ目以降のカラムの上方向に余白を指定します。

2カラム

2カラム以上になると少し複雑になります。

.st-Grids-col2 > .st-Grids_Item {
  width: percentage(1 / 2);

  /**
   * いったんすべての`margin-top`をリセットします。
   * `:nth-of-type(n+1)`は1つ目以降のすべての要素に適応されます。
   * リセット後に対象となる要素に`margin-top`を指定します。
   */
  &:nth-of-type(n+1) {
    margin-top: 0;
  }
  &:nth-of-type(n+3) {
    margin-top: $st-grids-row-gap;
  }
}
@include mq-up(md) {
  .st-Grids-col2Md > .st-Grids_Item {
    width: percentage(1 / 2);

    &:nth-of-type(n+1) {
      margin-top: 0;
    }
    &:nth-of-type(n+3) {
      margin-top: $st-grids-row-gap-md;
    }
  }
}

2カラム幅(50%)にします(3カラムだとpercentage(1 / 3)になります)。

width: percentage(1 / 2);

1カラムで指定した上方向の余白をリセットします(カラム数が変わっても(n+1)のままです)。

&:nth-of-type(n+1) {
  margin-top: 0;
}

2カラムなので3つ目以降のカラムに上方向の余白が入るように指定し直します(3カラムだと(n+4)になります)。

&:nth-of-type(n+3) {
  margin-top: $st-grids-row-gap;
}

メディアクエリを追加して上記と同じ指定をします。

@include mq-up(md) {
  .st-Grids-col2Md > .st-Grids_Item {
    width: percentage(1 / 2);

    &:nth-of-type(n+1) {
      margin-top: 0;
    }
    &:nth-of-type(n+3) {
      margin-top: $st-grids-row-gap-md;
    }
  }
}

均等でないカラムバリエーション

今までは均等なカラムのバリエーションを追加しましたが、4/12と8/12のように変則的なグリッドを追加することもできます。

.st-Grids-col4to8 > .st-Grids_Item {
  &:nth-of-type(odd) {
    width: percentage(4 / 12);
  }

  &:nth-of-type(even) {
    width: percentage(8 / 12);
  }

  &:nth-of-type(n+1) {
    margin-top: 0;
  }
  &:nth-of-type(n+3) {
    margin-top: $st-grids-row-gap;
  }
}

@include mq-up(md) {
  .st-Grids-col4to8Md > .st-Grids_Item {
    &:nth-of-type(odd) {
      width: percentage(4 / 12);
    }

    &:nth-of-type(even) {
      width: percentage(8 / 12);
    }

    &:nth-of-type(n+1) {
      margin-top: 0;
    }
    &:nth-of-type(n+3) {
      margin-top: $st-grids-row-gap-md;
    }
  }
}

カラム指定の親クラス(.st-Grids-col4to8)直下にあるカラムに対して指定をします。

.st-Grids-col4to8 > .st-Grids_Item {}

奇数を4/12に、偶数を8/12の横幅にします。

&:nth-of-type(odd) {
  width: percentage(4 / 12);
}

&:nth-of-type(even) {
  width: percentage(8 / 12);
}

均等なグリッドと同じように上方向の余白をリセットしてから、3つ目以降のカラムの上方向に余白を指定します。

&:nth-of-type(n+1) {
  margin-top: 0;
}
&:nth-of-type(n+3) {
  margin-top: $st-grids-row-gap;
}

まとめ

紹介したグリッドシステムはスタイルガイドと相性が良いです。
ページの量産のあとから余白の設計をしようとすると、大量のHTMLの修正が発生してしまうこともあります。ですので、スタイルガイドを作る場合はモジュール(コンポーネント)を作るのと同じくらい、余白やレイアウトの管理方法を考えておくことが大切です。

その他の余白の管理方法もデモやGitHubに載せていますので参考にしてみてください。

お問い合わせはこちら