- December 13, 2012
Beyond Binary Grids
Grids are everywhere on the web, and there is no hiding from them. We need grid systems to help create grids that are usable and manageable, and with Responsive Web Design, this has been a tricky tightrope to walk. We need our layouts to react to different media query breakpoints, and the way we have built grids in the past needs to be extended to do that.
One of my favorite methods for creating a grid is Nicole Sullivan’s OOCSS grid system. It’s a beautifully simple way to create a robust grid suitable for the majority of designs. However, it lacks a good solution for dealing with Responsive layouts.
Like a lot of grid systems, OOCSS grids use what I call a binary approach. At a certain size, floats are removed and column widths are set to 100%, creating a linear layout. The layout is either on or off. There is no gray area in between, and if we want those beautiful shades of gray, we’re either out of luck or stuck corrupting our grid system.
Contextual Classes
We want to go beyond a binary grid, but we want to retain the simplicity of OOCSS grids. What can we do? Writing rules to modify the layout in certain contexts seems like a possible approach, but it gets unruly quickly. The simple straightforwardness is lost, and, suddenly, we’re managing dozens of context-specific layout rules. My solution side steps this problem by using contextual classes.
We can duplicate our grid for each of our major breakpoints and use a class prefix to separate these different grids from each other. Applying multiple classes to a column in our HTML gives us a grid that adapts more robustly between a “mobile” scale and a “desktop” scale, while retaining all the desirable attributes of OOCSS grids (note: I’ve truncated the example code below):
.g-1of1 { width: 100%; }
.g-1of2 { width: 50%; }
.g-1of3 { width: 33.33333%; }
.g-2of3 { width: 66.66666%; }
…
@media only screen and (min-width: 25em) {
.g1-1of1 { width: 100%; }
.g1-1of2 { width: 50%; }
.g1-1of3 { width: 33.33333%; }
.g1-2of3 { width: 66.66666%; }
…
}
@media only screen and (min-width: 37.5em) {
.g2-1of1 { width: 100%; }
.g2-1of2 { width: 50%; }
.g2-1of3 { width: 33.33333%; }
.g2-2of3 { width: 66.66666%; }
…
}
For example, to build a layout where we have a column that will be 100% wide at our “mobile” breakpoints, we can apply a class of g-1of1 to that column. Now, let’s say we want that column to be 50% wide when the browser is wider than 37.5 ems (600 pixels). We also then apply a class of g2-1of2. Our HTML looks something like this:
<div class="col g-1of1 g2-1of2">
…
</div>
At 37.5 ems wide, this column will change its width to be 50% rather than 100%—all without defining a rat’s nest of context-specific styles in our CSS.
We can construct grids this way at different breakpoints directly in the HTML using classes. No mucking with complex grid libraries and inflexible context-sensitive rules in our CSS. I’ve posted a demo of a complete working grid system on CodePen for the curious among you.
Going Further
We can even extend this technique beyond grids if our hearts so desire. Say we want to show and hide certain content at different breakpoints. We could apply our display: none; property directly to our module at the breakpoint we want, but we’d need to do this every time we needed to hide content. Or, we could abstract this rule out into a helper class, .is-hidden, so we can control it in one place. We can even add a sister helper class, .is-shown, that will take a hidden piece of content and display it once more.
.is-hidden { display: none; }
.is-shown { display: block; }
Now, if we apply a breakpoint prefix to this same class in our different media queries, we suddenly can turn this content on and off at whatever breakpoint we please with the addition of a couple classes.
@media only screen and (min-width: 25em) {
.g1-is-hidden { display: none; }
.g1-is-shown { display: block; }
}
@media only screen and (min-width: 37.5em) {
.g2-is-hidden { display: none; }
.g2-is-shown { display: block; }
}
If we so choose, we can apply this technique rather broadly, creating a system that adapts to our media query breakpoints and provides a significant amount of flexibility.
For Teams and for Clients! Also, Classes!
This kind of system can work excellently when used in a team environment or passed along to clients. One of the benefits of using this kind of grid is that the system is transparent, easy to access, and easy to learn. A little knowledge of Responsive Web Design, a mobile-first process, and of how the system is intended to be used goes a long way. If your team or clients need your help understanding how the system is used, support them. Answer their questions and impart your knowledge. It won’t take long, and everyone will be working faster and more efficiently for it.
If you’re afraid of using classes like this in your HTML, I defer to Nicole Sullivan, once again, who notes that, classes are our friends. Strike a balance in your code between too-broadly-defined classes and a CSS architecture that drowns your ability to iterate and collaborate quickly and effectively.
What Do You Think?
I would love to hear others’ perspectives on this technique. Have you done something similar? If you have, how has it worked for you? If you’re in client services, how have your clients responded? How would you improve upon a system like this? What downsides have you noted? Or, if you’re doing something different, how does it compare? Is there another solution that you’ve come up with that may be even better? Please tweet your thoughts at us!