A guide to the Frameless grid
"Dig responsive design? Hate fluid grids? Try a Frameless grid." I was sold on the Frameless approach when I first laid eyes on that headline. But I had a hard time finding examples or technical explanations showing how the Frameless system is used, so it was difficult to get started. After figuring things out a bit, I decided to write this tutorial in the hopes that it will be useful to others.Â
Let me start by sharing links to the most useful resources I've found elsewhere.Â
This article by Pete Wailes doesn't go into technical detail; its purpose is to give you a high-level approach to designing for the Frameless grid system. Â
Stack Overflow user lolmaus offers a plain-English overview of the Frameless grid.Â
Another denizen of Stack Overflow, Davy8, explains Frameless's core LESS variables and mixins.Â
The Frameless stylesheet is implemented in both LESS and SASS, which are CSS preprocessors that allow for such goodies as variables, nested rules, and more. I elected to use the LESS version for this guide. If you're unfamiliar with LESS, I recommend spending a short time learning the basic concepts before continuing. I also assume you're well-versed in CSS.Â
An overview of the Frameless grid system
The unit of measurement in the Frameless grid system is the em. The em is unique in CSS because it doesn't have a fixed meaning; rather its value is relative to the font size of the parent element. Â
In typography, the em is traditionally the width of the capital letter M (hence the em-dash). CSS changes things up a bit by deriving the em from a vertical, rather than horizontal, measurement. As Jon Tan writes,Â
One em equals the vertical space needed for any given letter in a font, regardless of the horizontal space it occupies. Therefore: If the font size is 16px, then 1em = 16px. … at the default browser setting, 1em = 16px.Â
And following on that, if you set the font size of a div to 22px, then an em will equal 22 pixels inside that div. The fact that the size of an em is based on the font size of the parent element means that the em can mean different things on different parts of the same page. This introduces some complications to the Frameless system that I'll address later in this guide.
Here is the how the basic units of the Frameless grid are created in frameless.less:
@font-size: 16; // Your base font-size in pixels @em: @font-size*1em; // Shorthand for outputting ems, e.g. "12/@em" @column: 48; // The column-width of your grid in pixels @gutter: 24; // The gutter-width of your grid in pixels
Here, you set the widths of your single columns, gutters, and the base font size. From these measurements, the units of the Frameless grid—its columns—are calculated below:Â
// // Column-widths in variables, in ems // Â @1cols: ( 1 * (@column + @gutter) - @gutter) / @em; @1col: @1cols; Â @2cols: ( 2 * (@column + @gutter) - @gutter) / @em; Â @3cols: ( 3 * (@column + @gutter) - @gutter) / @em; Â @4cols: ( 4 * (@column + @gutter) - @gutter) / @em; Â @5cols: ( 5 * (@column + @gutter) - @gutter) / @em; Â @6cols: ( 6 * (@column + @gutter) - @gutter) / @em; Â @7cols: ( 7 * (@column + @gutter) - @gutter) / @em; Â @8cols: ( 8 * (@column + @gutter) - @gutter) / @em; Â @9cols: ( 9 * (@column + @gutter) - @gutter) / @em; @10cols: (10 * (@column + @gutter) - @gutter) / @em; @11cols: (11 * (@column + @gutter) - @gutter) / @em; @12cols: (12 * (@column + @gutter) - @gutter) / @em; @13cols: (13 * (@column + @gutter) - @gutter) / @em; @14cols: (14 * (@column + @gutter) - @gutter) / @em; @15cols: (15 * (@column + @gutter) - @gutter) / @em; @16cols: (16 * (@column + @gutter) - @gutter) / @em;
If you will need more columns for your layout, you can add them here; likewise you can remove unneeded columns.Â
These columns will be the building blocks of your layout. You use them as widths (and heights, if you like) the same way as you would other units in CSS. For example, if you want to float a 3-column div to the right of a 2-column div, you could write the following:Â
#firstDiv { width: @3cols; float: left; } #secondDiv { width: @2cols; margin-left: @gutter/@em; float: left; }
Note that you have to account for gutters in your code using the @gutter variable.
You also saw the following line above, which merits some discussion:Â
@em: @font-size*1em; // Shorthand for outputting ems, e.g. "12/@em"
You will want to use this shorthand in lieu of absolute measures such as pixels when you're setting sizes of things that won't be measured in columns, like font sizes, paddings, and margins. If you set a measurement as 16/@em, it resolves to 1em in CSS, which is equivalent 16 pixels because your base font size is 16.Â
Why do this instead of simply using pixels or points? Because if you zoom your whole layout in or out—which I'll show you how to do below—measurements in the above shorthand will zoom proportionally with the rest of your layout.Â
Once you have your columns set, you can set your basic styles and design your layouts, progressing from the smallest (mobile) to the largest. As your stylesheet progresses to larger, more complex layouts, you add columns to your grid, while styles are inherited from the smaller, simpler layouts—therefore it's truly mobile-first design.
A simple example using the Frameless grid
I've constructed a basic page to demonstrate the essentials of the Frameless grid. You can see the distinct layouts by resizing your browser window.
View the page's LESS stylesheet here. Note that there are distinct layouts for mobile, wide mobile, tablet, and desktop, each declared using @media queries. Additionally, I added one full-page zoom for widths of more than 1024 pixels.Â
(In your own design, of course, you can set these "breakpoints" wherever you'd like—wherever you feel they would make sense.)
Looking at the LESS stylesheet, you can see at line 151—starting with the comment
/**** common styles *****/
—is where basic styles, common to all layouts, are declared. Then, progressing down the stylesheet, we work our way from the smallest to largest layout sizes. Each size inherits styles from the smaller sizes that came before, while overriding previously-declared values when necessary.Â
At line 377, towards the end of the file, we see the full-page zoom. At sizes above 1024 pixels, the desktop layout is unchanged, but the following code enlarges the entire layout, including the background image:
body { font-size: (@font-size + 2)/16*1em; }
 Deciphering framelessgrid.comÂ
For a slightly more complicated Frameless setup, let's look at the framelessgrid.com site.Â
Its LESS source code can be seen here on Github. You now can see where I got the layout sizes for my demo—I used a simplified version of this setup, ommitting the huge-screen layout for screens above 118 ems.
Framelessgrid.com also uses a more complex set of full-page zooms. You can see that the full-page zooms are grouped in a section on their own, starting at line 581.Â
@media screen and (max-width: 16.875em) { body { font-size: (@font-size - 2)/16*1em; } #masthead, #introduction, article section, #colophon { padding-left: 10/@em; padding-right: 10/@em; } } @media screen and (max-width: 19.9375em) { body { font-size: (@font-size - 1)/16*1em; } } @media screen and (min-width: 32.5em) and (max-width: 37.4375em), screen and (min-width: 45em) and (max-width: 56.9375em), screen and (min-width: 77.5em) and (max-width: 102.4375em), screen and (min-width: 135em) { body { font-size: (@font-size + 1)/16*1em; } } @media screen and (min-width: 102.5em) and (max-width: 117.9375em), screen and (min-width: 150em) { body { font-size: (@font-size + 2)/16*1em; } }
You can see that there are five zoom levels used here. At the base "zero" level, 16/@em equals 16 pixels, and this doesn't need to be explicitly declared, because it's the default behavior.Â
font-size: (@font-size - 2)/16*1em;
indicates that the layout should be zoomed out by two levels.
font-size: (@font-size + 1)/16*1em;
indicates that the layout should be zoomed in by one level. And so on.Â
The fact that this full-page-zoom section is kept separate from the section styling the different layouts makes it a bit difficult to see the relationship between framelessgrid.com's layouts and zoom levels. I created the following chart to help make it more clear. The dotted lines delineate a change in layout. Shading shows the different zoom levels.
You can see here how this approach is appealing for those who "hate fluid layouts" but want to embrace the flexibility of responsive design. Between the distinct layouts created for different form factors, you can zoom your layout in or out to create intermediate steps. Therefore you can create a smooth progression of adaptations, and each change in your page's appearance represents a discrete and predictable step. You retain full control of your layout at all times. This isn't necessarily the case with fluid layouts.
There's no magic to the Frameless system that takes work off your hands—you still have to figure out how to position your elements in CSS as you did before. Hence, as its author writes,
Is Frameless a framework? Nope. It doesn’t include any code. [Not totally accurate! It does include some code, as we've seen.] It’s just an idea for a specific type of adaptive grid. You can use it as a good starting point for a new design, but you’ll still have to do all the hard work of designing and coding yourself.
Frameless is more of a set of tools, rules, and an approach that helps you build your own adaptive grid.
Some pitfalls and caveats
As I mentioned before, the em is the unit of measurement in the Frameless grid. That is to say, when your Frameless-based stylesheet goes through the CSS preprocessor, any measurement you specified in columns or the /@em shorthand are expressed in ems in CSS.
The em is also a unit that is defined as the font size of the parent element. So any element for which you might set a font size different from the base font size, like an <h3> or <p>, you probably don't want to size in columns or using the /@em shorthand, because you've fiddled with the meaning of an em by modifying the font-size. In short, if you size an element in columns and change its font size, you'll get unintended results. [But see the update at the end of this article for a workaround.]
Also be aware that even when sizing in columns, the rules of the CSS box model still apply. Therefore, if you set padding for your element, it will add to the total (visual) width of your element. This means that if you, say, set an element be @2cols in width, and then add padding to the left and/or right, the element will visually take up more than @2cols in width, possibly messing up your layout.
Here's the solution to both of the above pitfalls: Whenever you might run into these problems, separate the conflicting measures into parent (container) elements and child elements. In general, you might want to separate structural elements of your layout from its content.
This extra code will detract somewhat from the Zen-like purity of your HTML code. But other grid systems might be even less gentle with your markup.Â
In conclusion
I haven't been using Frameless for long. If I've made mistakes, misrepresented concepts, or completely missed the boat, let me know via e-mail or hit me up on Twitter.Â
Thanks for reading, and thanks to Joni Korpi for creating the Frameless grid system.Â
Update:Â Mark Root-Wiley writes in with a workaround for the sizing issues involving ems:
With my prior experiences with ems, I immediately saw the drawback you mentioned. I forged ahead regardless but got sick of the font-size-borks-width issues quite quickly. And that's when I realized that the work-around should have been obvious to me immediately. I've started coding some sites with rems recently and have loved it. You still need to provide a pixel fallback with rems, but A) there's at least a SASS mixin for that [which replaces using that $em measurement technique you mention] and B) Frameless Grid itself says to "Leave IE6-8 Behind," so giving those browsers the fallback doesn't really feel that dirty.
Google quickly showed me that I wasn't the first person to think of this, but I'm digging it in the hour since I reworked things to use it and so I thought I'd pass it along. I may be overlooking some really obvious reason why this will fail, but for now I'm thrilled and I wanted to pass it along in case you thought it worth mentioning in the article for others' benefit.










