Grid systems are a great way of positioning and ordering content in user interfaces. In modern web development, nearly every framework provides some kind of grid system.
Building a grid system for the web on my own has been on my list for quite a long time now. Every big framework includes one, Bootstrap maybe being the most popular. Of course, using a framework is a lot easier than writing a grid system from scratch, however, like with this blog, I’m really curious how things work technically and the best way to understand things like that is by building something on your own. And it’s fun, too!
Technological options
So far, I’ve seen three different approaches used by other people to build grid systems.
- Floats
- Flexbox
- Using
display: inline-block
The float based solution is the one used by most frameworks. Bootstrap 3 for example uses floats for its grid system. The main advantage here is that it will most probably work on a lot of browsers because floats have been around for quite some time now. On the other hand, it’s a hack. It’s not what floats have been made for and you have to ensure proper clearing and stuff.
Flexbox would be the most modern choice for building a grid system. It finally solves the positioning problems of CSS and allows to order elements independently of their semantic order. This offers possibilities that cannot be realized with floats. Unfortunately, it has a downside and that is IE support.
Another interesting approach I stumbled upon recently, is using display: inline-block
to „float“ elements next to each other. A grid system with this technique has been implemented by Nicolas Gallagher.
Implementation
I decided to go for the traditional float based solution because it theoretically works in all browsers and I already knew how it works. Maybe I’m going to build a flexbox based solution another day.
The actual implementation has been pretty easy. Using a CSS preprocessor - I use Sass - offers awesome flexibility. Rather than setting the number of cells that fit into one row of a grid to some unchangeable value and then writing the CSS for that, I wrote a solution that reads the desired number of cells per row from a variable and then automatically generates the CSS rules needed for that. As a consequence, it’s not just a grid system, but a framework for grid system generation!
I uploaded the sources to GitHub and open sourced it. The default value for grids per row is 10. If one needs something else, the value can be changed in src/_variables.scss
. Also configurable via a variable is the gutter between the cells. By using box-sizing: border-box
for the cells and using their padding to create the gutter, this has no implications on the the width of a cell.
I chose to use natural language for the sizing classes, you can get an impression by the example below or by visiting the demo page I created.
<div class="grid">
<div class="cell cell-half">
1/2 width
</div>
<div class="cell cell-half">
1/2 width
</div>
</div>
The grid system also provides some utility classes for cell alignment and offsets. Finally, I added support for generation of responsive cell sizing classes as well. By defining the width breakpoints in a Sass map and generating the cell sizing classes automatically, one can simply add more width breakpoints to the map and all the necessary cell sizing classes will be generated at the next compilation! Furthermore, I introduced a boolean variable, that can be used to disable the responsive cell sizing classes at compile time. If they aren’t needed, they shouldn’t go into the compiled CSS to keep the file size at a minimum.
Summary
I wrote a simple and lightweight grid system for CSS using the Sass preprocessor. Building the basic functionality took me an afternoon, adding the responsive cell sizing classes and the utilities a few additional hours the next day.
Of course there are grid systems which are more powerful and better tested across browser, however it was a nice project to improve my Sass skills and learn about the tech side of grid systems.
You can check out the sources at my GitHub respository.
Write a comment
via