JP
/
EN

CSS: 超軽量簡易レスポンシブグリッドIE11対応

IE11対応のレスポンシブな俺々超軽量簡易グリッドシステムをこしらえた。できればdisplay: grid;を使いたいところだが私はIEにも優しい紳士なのでdisplay: flex;のみで仕上げている。

Bootstrapなど既成のフレームワークを入れるほどではない、簡易で軽量なグリッドシステムだけが欲しい、という場面での活躍に期待。要望は以下の通り。

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

これが超軽量簡易俺々レスポンシブグリッドCSSだ!

Sass版は後述。

.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%; }
.row > [class*="col_"] { box-sizing: border-box; }
@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;
  }
}

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

CSSの適用方法はこんな感じ。指定した割合で左右に分割、分母(12)を超えたら下に回り込み、(max-width: 768px)を満たすと幅が100%になる。ナイスレスポンシブ。

<!-- 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の値は別に統一しなくてもいい。

最大カラム数の変更

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%; }

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

これが超軽量簡易俺々レスポンシブグリッドSassだ!

先ほどのCSSをSass (SCSS) にして、余白と分割数を指定しやすくしてみた。

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

@mixin row($denom, $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;
  @for $num from 1 through $denom - 1 {
    > .col_#{$num}_#{$denom} { @include col($margin, $denom, $num); }
  }
  > .col_#{$denom}_#{$denom} { width: 100%; }
  > [class*="col_"] { box-sizing: border-box; }
  @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;
    }
  }
}

/* ↓上記のmixinを使って任意のclassを作成 */
.row_1 {
  /* 分割数:12、カラム間の余白:10px、モバイル時の下余白:10px */
  @include row(12, 10px);
}
.row_2 {
  /* 分割数:6、カラム間の余白:10px、モバイル時の下余白:20px */
  @include row(6, 10px, 20px);
}

あとがき

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