A Non-Framework Grid System
I.
As a designer, I really don't like stylesheet frameworks. While I recognize their worth as a tool for piecing together a workable interface with little effort, my experience with them always seemed to rapidly deteriorate the minute I began to deviate from their idea of How Things Should Be Doneā¢. More often than not — unless there's a compelling reason why a framework is being used — I'll recommend ripping it out and starting over when coming on to an existing project.
That said, these frameworks usually come with a grid system, and grid systems are the way and the light for making things look great. The grid is to design what rhythm is to music; it allows us to anticipate what's coming next and heightens our sense of interaction with what we're seeing or hearing. It also makes a designer's job infinitely easier. It seriously felt like cheating when I first discovered grids way back in :cough: :cough:. No more pixel-fucking margins and padding, trying to "eye" what looked good.
So, how do we take advantage of our grid system while avoiding the headaches of stylesheet frameworks? Well, we use the magic of modern CSS preprosessors to define our baseline grid value as a variable that we can reuse throughout our stylesheets. As far as preprocessors go, I'm partial to SCSS, but it takes all kinds and I'm not going to fisticuffs over it. Port it as you may.
Here's what the top of pretty much all my stylesheets looks like:
// grid calculator
// a function to turn our pixels into ems
@function emificate($target, $context: $font_size) {
@if $target == 0 { @return 0 }
@return $target / $context + 0em;
}
// set our grid rhythm and font size
$grid: 30px; // set to your desired line-height and base grid unit
$font_size: $grid / 1.5 ; // set to your desired line-height ratio
// run our em functions and bulletproof our body font size
$line_height: emificate($grid);
$of-default-font-size: percentage($font_size / 16px);
body {
font-size: $of-default-font-size;
line-height: $line_height !important;
}
II.
Let's break down the code.
The first section is a function for converting our human-meaningful pixel values into em values for use in our browser (I think I originally swiped the function from Sassaparilla). This function allows us to set our default font size against typical browser defaults in the third section.
The second section is where we set our base grid size and our base font size. Keep in mind that our base grid size is going be used to define the paragraph-level line height (aka, the leading) of our text — this means the distance from the bottom of one line of text to the bottom of the line of text above it. Since our letters obviously need to fit in this space with room to spare, our font size is going to be smaller than our base grid value.
Now, it might seem odd that we're declaring our font size as a ratio of our base grid value instead of just calling it a pixel value. Anybody who has written a school paper is probably familiar with what's going on here, though it may not be recognizable since we're doing the math backwards. Remember single-spacing and double-spacing? Well, it's the same concept here, except instead of the font size determining how big the spacing is, we're using the spacing to determine the font size. (The reason for doing this backwards is so that we have a usable, whole-number value later on for determining asset and image sizes — the math can get really decimal-ly here, so it's best to hand the decimals off to the browser for computation as opposed to trying to make something 304.28756 pixels wide in Photoshop.) The lower the number being divided into our $grid here, the larger the font size. Feel free to experiment with this value, but keep in mind that a good ratio for readability here is usually between 1.3 and 1.6.
The third section is where we apply our Bulletproof Web Design principles and convert our default body font size as an em-value of browsers typical default font size settings of 16px. Go read that link again. If that still doesn't make sense, don't worry about it, you needn't grok that part to use the grid.
III.
So, why the hell did we go through all that? Well, we did it so that we have this:
$grid
We can now use this variable all throughout our stylesheets when declaring element widths, heights, paddings, and margins. We can multiply it, divide it, and even use negative values of it when necessary. For instance:
header {
width: $grid * 12;
margin: 0 auto $grid;
padding: $grid / 2;
background-position: -$grid 0;
}
If something is too small, multiply it until it's not:
.button {
width: $grid * 6;
}
If something is too big, divide it until it's not:
.button {
padding: $grid / 4;
}
Define your top-level widths as multiples of your grid:
$desktop-width: $grid * 32;
$tablet-width: $grid * 24;
$phone-width: $grid * 12;
article {
width: $desktop-width;
}
And more, all without mucking up your markup with style-specific classes. Use the grid when you want to, and deviate from it if necessary. I've found that defining and building my grid as I go is feels really nice, lightweight, flexible, and dependency-free, unlike a lot of stylesheet frameworks. This was proven to me towards the end of the very first project on which I used this method. The client suddenly declared that everything was too small. Normally, that would have been a huge pain in the ass, but because I stuck to my $grid I was able to make every element of the interface bigger while maintaining all my ratios with just a few keystrokes.