CSS: Simple responsive grid system (Supported IE11)

I made a responsive grid system that supports IE11. I’d like to use display: grid; if possible, but I’m an IE-friendly gentleman, so I made it only with display: flex;. I use it when I just want a simple grid system, not as much as using a framework like Bootstrap.

  • It also works on IE11.
  • Align the height of the columns.
  • Can also be nested.
  • Margins can be set freely.
  • No margins at the top and bottom.
.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;
  }
}

As you may have noticed, I’m an underscore sect. I’m sorry for those who don’t like it.

How to use

Like this.

<!-- 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>
<!-- If you don't want to line up on mobile -->
<div class="row not_fluid">
  <div class="col_6_12">col_6_12</div>
  <div class="col_6_12">col_6_12</div>
</div>

Demo page

How to customize

Change the margins

If you want to change the margin, modify the part where it is set to 15px. In the example, it is set to a fixed value of 15px, but you can also specify a percentage.

For 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)); }
/* (Omitted) */
.row:not(.not_fluid) > [class*="col_"] {
  width: 100%;
  margin-bottom: 8px;
}

For 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)); }
/* (Omitted) */
.row:not(.not_fluid) > [class*="col_"] {
  width: 100%;
  margin-bottom: 1%;
}

The margin-bottom and width values do not have to be the same.

It’s easy to centrally manage using CSS custom properties, but I’m a gentleman who is kind to IE, so I don’t do that. Gentlemen code with SCSS etc. to make it beautiful.

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

Change the maximum number of columns

It is described in 12 divisions, but you can increase it as much as you like by customizing it in the same way.

When dividing into 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)); }

When dividing into 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%; }

In the case of SCSS example, all you have to do is change the argument.

When dividing into 15 (SCSS):

& > .col_1_15 { @include col(15, 1); }
& > .col_2_15 { @include col(15, 2); }
& > .col_3_15 { @include col(15, 3); }

Afterword

May the world be more IE-friendly.

About Me

Hirota Yano / Programmer
Born in 1988, based in Japan

Languages

日本語 / English