CSS » Grid system

In­spired by Boot­strap, the grid sys­tem is the heart of a re­spon­sive web­site lay­out. The m-grid.css file con­tains all the set­up you need for it, it’s com­plete­ly stand­alone. Be­sides that, in or­der to have de­vices rec­og­nize your web­site prop­er­ly as re­spon­sive and not zoom it out all the way to an un­read­able mess, don’t for­get to add this to your <head>:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

Over­view

If you have nev­er heard of it, it all boils down to a few break­points that de­fine how the web­site is wide on var­i­ous screen sizes. For ev­ery one of them you can de­fine how your page and con­tent lay­out will look like. In ev­ery case you have 12 col­umns and it’s com­plete­ly up to you how you use them. Let’s start with an ex­am­ple.

<div class="m-container">
  <div class="m-row">
    <div class="m-col-t-6">.m-col-t-6</div>
    <div class="m-col-t-6">.m-col-t-6</div>
  </div>
  <div class="m-row">
    <div class="m-col-s-4 m-col-m-6">.m-col-s-4 .m-col-m-6</div>
    <div class="m-col-s-4 m-col-m-3">.m-col-s-4 .m-col-m-3</div>
    <div class="m-col-s-4 m-col-m-3">.m-col-s-4 .m-col-m-3</div>
  </div>
  <div class="m-row">
    <div class="m-col-l-7"><div class="m-frame m-center">.m-col-l-7</div></div>
    <div class="m-col-l-5"><div class="m-frame m-center">.m-col-l-5</div></div>
  </div>
</div>
.m-col-t-6
.m-col-t-6
.m-col-s-4 .m-col-m-6
.m-col-s-4 .m-col-m-3
.m-col-s-4 .m-col-m-3
.m-col-l-7
.m-col-l-5

In the above code, the out­er <div class="m-container"> is tak­ing care of lim­it­ing the web­site lay­out width. On very nar­row de­vices, the whole screen width is used, on wider screens fixed sizes are used in or­der to make the con­tent lay­out­ing man­age­able. The .m-container usu­al­ly has .m-row items di­rect­ly in­side, but that’s not a re­quire­ment — you can put any­thing there, if you just want to have some pre­dictable width lim­i­ta­tion to your con­tent.

The <div class="m-row"> de­notes a row. The row is lit­tle more than a de­lim­iter for col­umns — it just makes sure that two neigh­bor­ing rows don’t in­ter­act with each oth­er in a bad way.

The ac­tu­al mag­ic is done by the row el­e­ments de­not­ed by .m-col-B-N. The B is one of four break­points — t for tiny, s for small, m for medi­um and l for large — based on screen width. The N is num­ber of col­umns that giv­en el­e­ment will span. So, look­ing at the code above, .m-col-m-3 will span three col­umns out of twelve on medi­um-sized screen.

This set­ting is in­her­it­ed up­wards — if you spec­i­fy a col­umn span for a small­er screen width, it will get ap­plied on larg­er width as well, un­less you over­ride it with a set­ting for larg­er screen width. On the oth­er hand, if giv­en screen width has no col­umn width spec­i­fied, the el­e­ment will span the whole row. So, again from above, the .m-col-s-4 .m-col-m-6 el­e­ment will span the whole row on tiny screen sizes, four col­umns on small screen sizes and six col­umns on medi­um and large screen sizes.

De­tailed grid prop­er­ties

Break­point Screen width range (in­clu­sive) .m-container width Class­es ap­plied, or­dered by pri­or­i­ty
t, “tiny”, por­trait phones less than 576px full screen width .m-col-t-*
s, “small”, land­scape phones 576px - 767px 560px .m-col-s-*, .m-col-t-*
m, “medi­um”, tablets, small desk­tops 768px - 991px 750px .m-col-m-*, .m-col-s-*, .m-col-t-*
l, “large”, desk­tops, very large tablets 992px and up 960px .m-col-l-*, .m-col-m-*, .m-col-s-*, .m-col-t-*

Wrap­ping around

Be­sides the above “all or noth­ing” sce­nario, where all the el­e­ments ei­ther form a sin­gle row or are laid out one af­ter an­oth­er in sep­a­rate rows, it’s pos­si­ble to wrap the items around so they for ex­am­ple take four col­umns in a large screen width and two rows of two col­umns in a small screen width. In such case it’s im­por­tant to ac­count for el­e­ments with dif­fer­ent heights us­ing a .m-clearfix-* for giv­en break­point:

<div class="m-container">
  <div class="m-row">
    <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...<br/>...</div>
    <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3</div>
    <div class="m-clearfix-s"></div>
    <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...</div>
    <div class="m-col-s-6 m-col-m-3">.m-col-s-6 .m-col-m-3<br/>...</div>
  </div>
</div>
.m-col-s-6 .m-col-m-3
...
...
.m-col-s-6 .m-col-m-3
.m-col-s-6 .m-col-m-3
...
.m-col-s-6 .m-col-m-3
...

Push­ing and pulling

It’s pos­si­ble to push and pull the el­e­ments around us­ing .m-push-* and .m-pull-* and even use this func­tion­al­i­ty to hor­i­zon­tal­ly re­order con­tent based on screen width. Learn by ex­am­ple:

<div class="m-container">
  <div class="m-row">
    <div class="m-col-l-6 m-push-l-3">.m-col-l-6 .m-push-l-3</div>
  </div>
  <div class="m-row">
    <div class="m-col-s-8 m-push-s-4">.m-col-s-8 .m-push-s-4<br/>first</div>
    <div class="m-col-s-4 m-pull-s-8">.m-col-s-4 .m-pull-s-8<br/>second</div>
  </div>
</div>
.m-col-l-6 .m-push-l-3
.m-col-s-8 .m-push-s-4
first
.m-col-s-4 .m-pull-s-8
second

Float­ing around

It’s al­so pos­si­ble to re­spon­sive­ly float or align the el­e­ments around us­ing m-left-*, m-right-* and m-center-* if you put the .m-col-* el­e­ments di­rect­ly in­to text flow with­out wrap­ping them in a .m-row el­e­ment. The fol­low­ing ex­am­ple will float the con­tents to the right on medi­um-size screens, cen­ter them on small and put them full-width on tiny screens:

<div class="m-col-s-6 m-center-s m-col-m-4 m-right-m">
  .m-col-s-6 .m-center-s .m-col-m-4 .m-right-m
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
.m-col-s-6 .m-center-s .m-col-m-4 .m-right-m

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Left-aligned float­ing blocks ad­di­tion­al­ly have 1rem pad­ding on the right and right-aligned blocks on the left. All of them have im­plic­it­ly pad­ding on bot­tom, ex­cept if the el­e­ment is a last child. Add a .m-nopadb class to them to dis­able bot­tom pad­ding, if you want to pre­serve it even for a last child, add an emp­ty <div></div> el­e­ment af­ter.

Grid pad­ding

The .m-container el­e­ment pads its con­tents from left and right by 1rem; the .m-row adds a neg­a­tive -1rem mar­gin on left and right to re­set it. Fi­nal­ly, the .m-col-* el­e­ments have 1rem pad­ding on all sides to sep­a­rate the con­tents. It’s pos­si­ble to over­ride this on the .m-container and/or on .m-col-* el­e­ments us­ing .m-nopad, .m-nopadx, m-nopady, .m-nopadt, .m-nopadb, .m-nopadl, .m-nopadr which re­move all, just hor­i­zon­tal or ver­ti­cal pad­ding, or pad­ding on the top/bot­tom/left/right, re­spec­tive­ly.

Grid nest­ing

It’s pos­si­ble to nest the grid. Just place a .m-row el­e­ment in­side an .m-col-* (it doesn’t need to be a di­rect child) and put your .m-col-* el­e­ments in­side. The in­ner grid will al­so have 12 col­umns, but small­er ones.

Re­mov­ing the grid on larg­er screen sizes

The usu­al be­hav­ior is to add the grid for larg­er screen sizes, but some­times you might want to do the op­po­site. It’s pos­si­ble to do that just by spec­i­fy­ing .m-col-*-12 for giv­en break­point, but some­times the CSS float prop­er­ty might cause prob­lems. The .m-col-*-none class­es com­plete­ly re­move all grid-re­lat­ed CSS styling for giv­en screen size and up so the el­e­ment be­haves like in its ini­tial state.

<div class="m-container">
  <div class="m-row">
    <div class="m-col-s-8 m-col-l-none">.m-col-s-8 .m-col-l-none</div>
    <div class="m-col-s-4 m-col-l-none">.m-col-s-4 .m-col-l-none</div>
  </div>
</div>
.m-col-s-8 .m-col-l-none
.m-col-s-4 .m-col-l-none

Hid­ing el­e­ments based on screen size

The .m-show-* and .m-hide-* class­es hide or show the el­e­ment on giv­en screen size and up. Use­ful for ex­am­ple to show a dif­fer­ent kind of nav­i­ga­tion on dif­fer­ent de­vices.

<div class="m-show-m">.m-show-m<br/>shown on M and up</div>
<div class="m-hide-l">.m-hide-l<br/>hidden on L and up</div>
.m-show-m
shown on M and up
.m-hide-l
hidden on L and up

In­flat­able nest­ed grid

It’s usu­al that the con­tent area of the page doesn’t span the full 12-col­umn width in or­der to avoid long un­read­able lines. But some­times one might want to use the full avail­able width — for ex­am­ple to show big pic­tures or to fit many things next to each oth­er.

If you have a ten-col­umn con­tent area with one col­umn space on each side, mark your .m-container el­e­ment with .m-container-inflatable and then put your nest­ed con­tent in el­e­ments marked with .m-container-inflate.

<div class="m-container m-container-inflatable">
  <div class="m-row">
    <div class="m-col-l-10 m-push-l-1">
      <div class="m-container-inflate">.m-container-inflate</div>
    </div>
  </div>
</div>
.m-container-inflate

The .m-container-inflate block has im­plic­it­ly a 1rem pad­ding af­ter (but not on oth­er sides and al­so not if it’s the last child). Add a .m-nopadb class to it to dis­able that, if you want to pre­serve the pad­ding even for a last child, add an emp­ty <div></div> el­e­ment af­ter.

It’s al­so pos­si­ble to tuck float­ing con­tent out of the page flow by com­bin­ing .m-left-* with .m-container-inflate:

<div class="m-container m-container-inflatable">
  <div class="m-row">
    <div class="m-col-l-10 m-push-l-1">
      <div class="m-container-inflate m-col-l-6 m-right-l">
        .m-container-inflate .m-col-l-6 .m-right-l
      </div>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id
      elit posuere, consectetur magna congue, sagittis est. Pellentesque
      est neque, aliquet nec consectetur in, mattis ac diam.</p>
    </div>
  </div>
</div>
.m-container-inflate .m-col-l-6 m-right-l

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id elit posuere, consectetur magna congue, sagittis est. Pellentesque est neque, aliquet nec consectetur in, mattis ac diam.

De­bug CSS

It’s some­times hard to see why the lay­out isn’t work­ing as ex­pect­ed. In­clud­ing the m-de­bug.css file will high­light the most usu­al mis­takes — such as .m-row not di­rect­ly con­tain­ing .m-col-* or two .m-containers nest­ed to­geth­er — with bright red back­ground for you to spot the prob­lems bet­ter:

<link rel="stylesheet" href="m-dark.css" />

Oth­er than high­light­ing prob­lems, this file doesn’t al­ter your web­site ap­pear­ance in any way. To save un­nec­es­sary re­quests and band­width, I rec­om­mend that you re­move the ref­er­ence again when pub­lish­ing the web­site.