For months, even before working at Vox Media, I’ve been working away at a pet project called Singularity, a grid system for Sass and Compass. The idea behind Singularity is to create a grid system that will work not only with uniform grids, but also grids built on modular scales. After numerous pitfalls and refactors, Singularity is now entering beta, built on a solid codebase with more flexibility than was originally planned.
The state of grids for the web
Almost every grid system for the web today is built on relatively modern concepts. The book that holds the core principles behind these is Grid Systems in Graphic Design by Josef Muller-Brockmann; it serves as the bible of modern grid construction. In this book Muller-Brockmann outlines how to divide the page into rows and columns with equal gutters. He also illustrates how to position content and imagery on these grids to create truly wonderful layouts. These concepts of page construction have become a standard for designers, and for good reason. Uniform grids are easy to create, implement, and use in design as well as providing much needed order to the wide array of content designers need to deal with today. However, this type of grid is only the current fashion in a history filled with a wonderful variety of incredible grids waiting to be revived.
Reviving the cannons of page design
After working on a Compass plugin used to calculate modular scales, I became fascinated with classical layout geometry. Geometry in design is no new thing, of course. Typographer and book designer Jan Tschichold wrote:
"Though largely forgotten today, methods and rules upon which it is impossible to improve have been developed for centuries. To produce perfect books these rules have to be brought to life and applied." (Hendel, Richard. On Book Design. New Haven: Yale UP, 1998. Print.)
The golden section is the most common proportion used in book design. The Greeks used it liberally, and it even shows up in the Gutenberg Bible. But the golden section isn’t the only ratio available. Musical scales have been applied to European design for over 1000 years to create rhythm and harmony between layout and typography.1 The layout pictured above is called "secret canon" and utilizes fifth and octave scales. This layout can be found in the pages of books and manuscripts throughout medeval times and more recently in the pages of Penguin Books. These relationships can also be found in our gadgets: for example the iPad aspect ratio corresponds to a musical fourth, and HDTV uses 9:16 — a minor 7th.2 This kind of layout geometry may seem rigid, but it can offer some intriguing possibilities that make a design resonate. My goal in making Singularity has been to bring these mathematical layout principles to web design.
Much of design is about proportion or the relationship between different sized objects on a page. A ratio of 1:2, or octave, simply means one element is twice the size of the first. A modular scale is a list where each number up and down the scale shares this same proportional relationship. The golden ratio is 1:1.618, and is unique because the next two measures down the scale can be added to equal the initial measure. This makes the golden ratio resonate within itself in a way no other ratio does. Studies have even concluded that our eyes scan using some of these basic patterns.
Developing a system
On March 6, 2012, I built a proof-of-concept that supported both modular scales and uniform columns. However, I discovered that moving different sized columns around was nearly impossible, and the code was clumsy. That attempt also relied heavily on silent selector behavior in an alpha version of Sass to optimize CSS output. This was a recipe for disaster, since changes would break the way Singularity generated responsive grids.
Meanwhile Gridset, a fantastic tool for building grids, was moving forward integrating the same features (and a whole lot more) into a WYSIWYG tool. I had all but scrapped my pet project until I ran across a proposal for asymmetric grids in Susy, the de facto grid system for Compass. While integrating into Susy seemed difficult, it was exactly what Singularity needed. The proposal was simply to list the various column widths. Because Susy is not aware of the current column, it would require some major changes to the syntax - but Singularity was already aware of the location of columns on a grid. Due to this new insight, progress on Singularity became swift, and the code more elegant.
Simple, but powerful
Early iterations of the Singularity grid system were highly specific in how they worked. It allowed for only two types of grids, each with its own set of logic. Using a list for columns changed this, and allowed for one set of logic for any kind of grid.
For example, a grid with three equal columns can be expressed as
$columns: 3; or
$columns: 1, 1, 1; or even
$columns: 33.3333%, 33.3333%, 33.3333%;. All three of these get parsed in the same way with the same result. Modular scales can be calculated and plugged into the same system easily by simply writing
$columns: ms(1), ms(2), ms(3); where each
ms() function writes a value going up a defined scale. Arbitrary values can be written in
$columns: 123px, 473px, 300px;.
The real power comes when plugging into this system. I discovered that functions can write lists to manipulate the relationships between columns, thereby creating any kind of grid. To test this theory out, I wrote a grid-compounding function that layers two uniform grids together to create a more complex one.
This function that multiplies the grids to find a common resolution, and includes a loop to identify where breaks fall on the grid. I also added a function to repeat grid patterns. This allows a designer to declare a pattern of values (like
1, 2, 3) and repeat them on the grid infinitely. Anyone can write a function to plug into the framework, allowing Singularity to accommodate a variety of needs.
Padding things out
Padding can be just as important to layout as columns or gutters. Particularly in designs when sidebars may be a different color, text needs room to breathe, so integrating padding was a must. Uniform padding can easily be added using
$padding: 1em;. But why stop there? Using Sass list functions it is possible to create and parse multi-dimensional lists, so that non-uniform padding can be added to the list of non-uniform columns. Simple! If you want the first column of three to have 10px padding instead of the default, just write
$columns: 1 10px, 1, 1;
One challenge was creating a system that can make complex and diverse layouts easy to use. So I decided to develop an array of simple tools to write layouts. At the core of every measurement in the system is a simple function that requires the user to specify how many columns to span and its location on the grid. Functions, in general, are particularly useful when building a foundation because they only declare a value and no other CSS - so they can be used for padding, margins, or anywhere else that value might be needed.
While this is nice to have, it requires a great deal of work from developers. So I identified two common ways people work with grid systems and wrote tools to aid each of these methods.
The most common and traditional way to use grid systems in CSS is with an array of classes. In Singularity, the mixin
@include grid-objects($prefix, $columns, $gutter, $padding, $selector); will do this for you, creating an array of objects you can use and embed at various breakpoints. Unlike most grid systems, is writes to an array of silent selectors rather than directly the CSS.
Silent selectors are selectors written in Sass, but not written in CSS unless they are called upon. If you want to call the first to third column for your article, there’s no need to add classes to HTML. Just invoke it in your Sass file with
@extend %a1-3;. If you prefer classes, simply define
$selector: "."; and the classes will be written for you to call in your HTML like
The other method used to write grids has been pioneered by Susy and their Semantic Grid System, where style is written directly to selectors instead of to an array. With this approach, developers can focus on the semantics of the content (instead of the layout) when building out a website. It can also reduce CSS file size on smaller sites. The mixin declares hom many columns an element spans, along with its starting location
@include grid-span($columns, $location);. But to make things even simpler, location is counted automatically. If you design using markup order, Singularity will follow you across your grid.
After months of research, iteration, and discovery, the code and capabilities of Singularity have transformed. Though Singularity is entering beta, it still has wrinkles. With a little ironing, hopefully Singularity will help raise the bar for layouts on the web and provide a foundation that can support the designs of the future.
You can find installation and usage instructions on Singularity at singularity.gs
Fork on GitHub: github.com/scottkellum/Singularity
1. Bringhurst, Robert. "Shaping the Page." The Elements of Typographic Style. Point Roberts, WA: Hartley & Marks, 2004. 144. Print
2. For more information on this I highly recommend The Elements of Typographic Style by Robert Bringhurst, Chapter 8. Understanding this context can help the designer make choices that will harmonize with these contexts. In Bringhurst’s words, "The mathematics are not here to impose drudgery on anyone … they are here entirely for pleasure."