CSS|IE11対応版レスポンシブ簡易グリッドシステム

IE11対応のレスポンシブな俺々グリッドシステムをこしらえた。できればdisplay: grid;を使いたいところだが、私はIEにも優しい紳士なのでdisplay: flex;のみで仕上げている。Bootstrapなど既成のフレームワークを入れるほどではない、単純なグリッドシステムだけが欲しい、という場面で活躍できるだろう。機能を絞ってシンプルに仕上げたのでカスタマイズも容易である。

要望:

  • IE11に対応したい。
  • カラムの高さを揃えたい。
  • 入れ子でも使いたい。
  • 余白を自由に設定したい。
  • 上下に余白をとりたくない。

完成品がこちら:

.row {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-box-pack: justify;
  justify-content: space-between;
}
.row > .col_1_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 1 + 15px * (1 - 1)); }
.row > .col_2_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 2 + 15px * (2 - 1)); }
.row > .col_3_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 3 + 15px * (3 - 1)); }
.row > .col_4_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 4 + 15px * (4 - 1)); }
.row > .col_5_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 5 + 15px * (5 - 1)); }
.row > .col_6_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 6 + 15px * (6 - 1)); }
.row > .col_7_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 7 + 15px * (7 - 1)); }
.row > .col_8_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 8 + 15px * (8 - 1)); }
.row > .col_9_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 9 + 15px * (9 - 1)); }
.row > .col_10_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 10 + 15px * (10 - 1)); }
.row > .col_11_12 { width: calc((100% - 15px * (12 - 1)) / 12 * 11 + 15px * (11 - 1)); }
.row > .col_12_12 { width: 100%; }
@media (max-width: 768px) {
  .row:not(.not_fluid) > [class*="col_"] {
    width: 100%;
    margin-bottom: 15px;
  }
  .row:not(.not_fluid) > [class*="col_"]:last-child {
    margin-bottom: 0;
  }
}

お気づきかもしれないが私はアンダースコア派である。気に障った方は申し訳ない。

使い方

こんな感じ。

<!-- 1:1 -->
<div class="row">
  <div class="col_6_12">col_6_12</div>
  <div class="col_6_12">col_6_12</div>
</div>
<!-- 1:2 -->
<div class="row">
  <div class="col_4_12">col_4_12</div>
  <div class="col_8_12">col_8_12</div>
</div>
<!-- 回り込ませない(モバイルで一列にしない) -->
<div class="row not_fluid">
  <div class="col_6_12">col_6_12</div>
  <div class="col_6_12">col_6_12</div>
</div>

デモページ

カスタマイズ方法

余白の変更

余白を変えたい場合は15pxとしている個所を修正する。上記では15pxと固定値にしているが、パーセント指定で割合にすることも可能。

8pxにする場合:

.row > .col_1_12 { width: calc((100% - 8px * (12 - 1)) / 12 * 1 + 8px * (1 - 1)); }
.row > .col_2_12 { width: calc((100% - 8px * (12 - 1)) / 12 * 2 + 8px * (2 - 1)); }
.row > .col_3_12 { width: calc((100% - 8px * (12 - 1)) / 12 * 3 + 8px * (3 - 1)); }
/* (中略) */
.row:not(.not_fluid) > [class*="col_"] {
  width: 100%;
  margin-bottom: 8px;
}

1%にする場合:

.row > .col_1_12 { width: calc((100% - 1% * (12 - 1)) / 12 * 1 + 1% * (1 - 1)); }
.row > .col_2_12 { width: calc((100% - 1% * (12 - 1)) / 12 * 2 + 1% * (2 - 1)); }
.row > .col_3_12 { width: calc((100% - 1% * (12 - 1)) / 12 * 3 + 1% * (3 - 1)); }
/* (中略) */
.row:not(.not_fluid) > [class*="col_"] {
  width: 100%;
  margin-bottom: 1%;
}

※margin-bottomとwidthの値は別に統一しなくてもいい。

CSSカスタムプロパティを使えば一元管理できて楽なのだが、IEにも優しい紳士なのでそんな真似はできない。紳士はSCSSなどでコーディングして美しくする。mixinにすれば複数パターンで作り放題だ。

SCSS版:

@mixin col($margin: 0px, $denom: 12, $numer :1) {
  width: calc((100% - #{$margin} * (#{$denom} - 1)) / #{$denom} * #{$numer} + #{$margin} * (#{$numer} - 1));
}

@mixin row($margin: 0px, $margin_bottom: $margin) {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-box-pack: justify;
  justify-content: space-between;
  > .col_1_12 { @include col($margin, 12, 1); }
  > .col_2_12 { @include col($margin, 12, 2); }
  > .col_3_12 { @include col($margin, 12, 3); }
  > .col_4_12 { @include col($margin, 12, 4); }
  > .col_5_12 { @include col($margin, 12, 5); }
  > .col_6_12 { @include col($margin, 12, 6); }
  > .col_7_12 { @include col($margin, 12, 7); }
  > .col_8_12 { @include col($margin, 12, 8); }
  > .col_9_12 { @include col($margin, 12, 9); }
  > .col_10_12 { @include col($margin, 12, 10); }
  > .col_11_12 { @include col($margin, 12, 11); }
  > .col_12_12 { width: 100%; }
  @media (max-width: 768px) {
    &:not(.not_fluid) > [class*="col_"] {
      width: 100%;
      margin-bottom: $margin_bottom;
    }
    &:not(.not_fluid) > [class*="col_"]:last-child {
        margin-bottom: 0;
    }
  }
}

.row_hoge {
  @include row(10px);
}
.row_huga {
  @include row(20px, 10px);
}

最大カラム数の変更

12分割で記載したが、同じ要領でカスタマイズすればいくらでも増やせる。

15分割にする場合:

.row > .col_1_15 { width: calc((100% - 15px * (15 - 1)) / 15 * 1 + 15px * (1 - 1)); }
.row > .col_2_15 { width: calc((100% - 15px * (15 - 1)) / 15 * 2 + 15px * (2 - 1)); }
.row > .col_3_15 { width: calc((100% - 15px * (15 - 1)) / 15 * 3 + 15px * (3 - 1)); }
/* 以下同様 */

もちろん減らすこともできる。

4分割にする場合:

.row > .col_1_4 { width: calc((100% - 15px * (4 - 1)) / 4 * 1 + 15px * (1 - 1)); }
.row > .col_2_4 { width: calc((100% - 15px * (4 - 1)) / 4 * 2 + 15px * (2 - 1)); }
.row > .col_3_4 { width: calc((100% - 15px * (4 - 1)) / 4 * 3 + 15px * (3 - 1)); }
.row > .col_4_4 { width: 100%; }

先ほどのSCSSの例であれば引数を変えるだけで済む。

15分割にする場合(SCSS版):

& > .col_1_15 { @include col(15, 1); }
& > .col_2_15 { @include col(15, 2); }
& > .col_3_15 { @include col(15, 3); }
/* 以下同様 */

あとがき

世界がもっとIEに優しくなりますように。 IEェ……。


矢野ヒロタ /1988年生まれ。プログラマー、会社員。仕事で培ったWebやスマホアプリの技術を発信すると見せかけてもっぱら妄想を綴っています。よしなに。