Singularity: a modern grid framework
Everybody has a grid system these days. Frankly, I’m not surprised. There are so many different ways to deal with drawing elements across a grid and with CSS grid layout on the horizon the options for creating grids are only going to grow. People also like to use different class structures and naming schemes in their code, or want something different from a static 12 column grid. Handling breakpoints has made things even more complicated. Chris Coyer wrote a post Don’t over think grids that explains how easy it is to roll your own grid but as a project evolves your grid might evolve into something a lot more robust, and sometimes launched as yet another new grid system. Yes, a basic grid is pretty simple to make but why reinvent the wheel? If you want something more complex, it’s nice to have those extra grid tools there and ready to go.
Singularity is a dramatic departure from other grid systems in a number of ways. Most importantly, it is a grid framework, not just a grid system. As a result, you can completely customize every aspect of your grid. If you want to use table-cell instead of floats, you can leverage the output API to do this, even switch output styles on the fly in the same stylesheet. You can run a loop to generate layout classes of your choosing at various breakpoints or use the mixins included to apply grid styles directly to things in your stylesheet. The point is to create a framework that is flexible and future friendly enough to work for you. If you want to add anything, write a plugin. We spun off some extras of our own to get the plugin party started. But really, every function and mixin is modular and, while we have an API for output and grid generation, it would be easy to re-write any one component on top of Singularity.
Ratio based math
The math behind Singularity is also different from other grid systems. Most grids are calculating by dividing the context, lets say 100%, into equal parts. A twelve column grid is one divided into twelve equal parts with gutters subtracted from that sum. Singularity calculates grids based on internal proportions. Instead of dividing by the context, the context is dynamically generated from a list of parts. Using the 12 column grid, it would be split into an array
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] and each part divided by 12 to make that column width. Gutters are built on this same system so if your gutter value is .5 then it is half the size of a grid column. I know this sounds really complicated, but all the complexities are hidden away and it really is quite easy once you get used to it. There are huge advantages to building a grid on this mathematical foundation. In context based math gutters will always shrink as the context shrinks but in this ratio based math the gutters are proportionate to the columns. As the number of columns grows and shrinks the gutters will scale to match them. To explain this in an array, a three column grid with .5 gutters would look like this
[1, .5, 1, .5, 1] and a two column grid would look like this
[1, .5, 1]. The context is the sum of all the parts and therefore the gutter in the two column grid will be a scaled up version of the gutter in the three column grid.
You might have caught the other advantage to ratio based math by now and that is arbitrary arrays can be used for the various columns. Instead of writing
3 to calculate a three column grid that is parsed like this
[1, 1, 1] you can write
1 2 1 to generate an array where the center column is twice as large as the first and last columns
[1, 2, 1]. Using this logic, you aren’t stuck with uniform column widths anymore. You can build grids where columns get wider, narrower, or are completely arbitrary. You can write simple functions to build out arrays that generate grids of all different shapes and sizes.
If you know how ratios work, you probably know that
30px:60px is the same as writing
1:2. Now, pixel perfection in responsive is a lie, but lets say you get a Photoshop comp and the grid is all measured out in pixels. You have twelve columns of
60px and gutters that are
20px. No more math, lets just write your columns twelve times
60px 60px 60px 60px 60px 60px 60px 60px 60px 60px 60px 60px and leave our gutters at
20px. Context is automatically calculated at 940px and percentages are generated based on that math. Maybe you get handed a comp where one column is annoyingly one pixel off from the rest. You can easily account for that as well. It’s the power of ratios at work. And hey, if you happen to want something that is fixed-width, just fix your container to a fixed size to achieve true pixel perfection.
Breakpoints no longer pain-points
Singularity comes bundled with Breakpoint which is just a mixin to help you write and manage your breakpoints. However it does have a killer feature of being able to query your context. So when writing
@include breakpoint(40em) Singularity knows you are in the context of
40em and will deliver the appropriate grid. Writing
$grids: add-grid(6 at 40em); will write a six column grid at that breakpoint. Breakpoint (the plugin) now knows that this is the grid you want to use whenever you are in this context. It’s magic being able to call on your grid no matter where you are without having to worry if it is the correct grid for that context. In-between breakpoints? Singularity knows and will be sure to write the one for those awkward in-between moments.
Grids on the fly
Different parts of our page have different requirements. In some places we may need to float elements across a page and in others design may dictate rigid positioning of elements to a slightly different grid. Nothing in Singularity is set in stone and within each function and mixin you can completely redefine your settings. This is particularly useful when nesting grid elements. If you have a grid with columns defined
[1, 2, 3] and are within the context of
[2, 3] you can simply use
@include grid-span(1, 1, 2 3) to span that center column while inside the last two columns. If you need to swap output modes you can write
$output-style: 'float' inside the
grid-span function to change the style on the fly. It’s impossible to lock yourself into a decision with Singularity because you can constantly change and fine tune everything throughout your stylesheet.
Singularity is what you make of it
I always get the question “Why is it called Singularity?” In astrophysics a singularity is an infinitely small point in space that has infinitely high mass, or, the center of a black hole. Ray Kurzweil also theorizes that technological evolution will reach a threshold where it iterates and can evolve on its own. I tried to make Singularity the best distillation of all the knowledge of grids I could find and deliver it in a powerful and scaleable form. Something that exists in a form that can transcend itself. These are lofty goals but hopefully Singularity meets them. The true test of these qualities will be in seeing what you the community does with Singularity, how you extend it, work with it, and push it past its limits. My good friend Sam Richard has already put in tons of work to bring 1.0 to completion and I hope the community is as excited about it as we are.