REMMY: A Calc() Based Grid Framework

Spire Digital
Spire Digital
Feb 11, 2016

The Pitfalls of Traditional Grids

Front-end grid frameworks generally fall into two categories: fixed-width or fluid. Fixed-width frameworks are rigid and inflexible; they don’t scale or maximize the extra space between breakpoints. Fluid frameworks do maximize all available space between breakpoints, but because they work off of percentages, gutters are often squashed and don’t maintain their structural or visual integrity.

The following example shows a fixed-width layout using SUSY. If you’re viewing this post on a monitor greater than 768px wide, you’ll notice that there is whitespace on either side of the container element. Resizing the container will not change the width of the inner elements.

This next example shows the same layout, but using a fluid grid with SUSY. Each element and it’s gutter is scaled by percent based on the current breakpoint width. Notice the gutter width increases or decreases when the container is scaled, causing inconsistencies with the bottom margins.

The solution: REMMY

REMMY uses calc() to determine column and gutter sizes. The layout below shows the same 8 elements, but while the container is resized, each element maximizes its allotted space without losing it’s static gutter width. There are no inconsistencies between vertical and horizontal margins.

The benefit to using calc() is that the calculations are made in real-time; the ability to mix measurements and values now exists. For instance, calculating the width of an element that is 3 out of 8 columns with a gutter of 1rem can be written like so:

div.three_of_eight {
width: calc( (3 / 8 * 100%) - 1rem + (3 / 8 * 1rem) );

This calc() statement is broken into 3 parts:

  • The initial width of the element: n columns out of the total columns (3/8 out of 100%)
  • Subtract the gutter width from the total element width
  • Add back 3/8 of 1 gutter (the last element in the container will have an omega supplied so that the gutter removed and the element is flush with the container)

You’ll notice there are no actual measurements used here except to determine the amount of space reserved for gutters. That is the key to maintaining flexible columns with fixed gutters.

Below is an example of a product page layout with a hero area, sidebar, and product grid:

Import and Setup REMMY

To implement REMMY, simply download the SCSS file here, and include it at the top of your SCSS project like so:

@import _remmy;

REMMY has only a few default variables to set: column widths and paddings, gutter widths, breakpoints, and container type. You’ll notice that the configurations are based loosely off of SUSY 1.

Responsive Breakpoint/viewport widths (in columns)
The values are arbitrary and can be customized
$breakpoints: (
mobile 4,
mobile-wide 6,
tablet 8,
tablet-wide 10,
desktop 12,
desktop-wide 16
Framework Settings
Column widths must be greater than 0.
Gutter and padding can be 0rem or greater.
$grid-column-width: 4rem;
$grid-gutter: 1rem;
$grid-padding: 1rem;
$grid-type: fluid; /* container max-width is 100% */
/* or ... */
$grid-type: magic; /* container max-width is same as breakpoint */


Containers are used to to house elements with column-based widths. It’s primary function is to clear floats.

section {
@include container();

Breakpoints are simply shortcuts for breaking out code at specific screen resolutions. Media queries are generated based on the width of columns, gutters and total columns set per breakpoint.

div {
@include breakpoint(desktop) { ... }

By default columns inherit the total number of columns at any breakpoint, or a total number of columns can be specified at the column declaration.

div {
/* base breakpoint is mobile */
@include cols(1);

@include breakpoint(tablet) {
/* total columns is specified (n out of specified total) */
@include cols(1,3);


Because REMMY utilizes FlexBox, it is no longer necessary to leverage omegas or right-floats for nth() or last() elements.


Please feel free to download, use, or modify REMMY as it suits you. If you have any improvements or suggestions, offer them as pull-requests in the repository.

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. We also share information about your use of our site with our social media, advertising and analytics partners. Read our cookie policy here

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.