Distributed knowledge with Compass

People tend to think of Compass as simply a mixin library. And while it’s true that Compass contains a great mixin library of the same name, it also provides tools to compile projects and to create frameworks that expand on its inherent capabilities. These frameworks can be used throughout your projects and distributed as Compass extensions. Although Compass is often compared with Bourbon, the two aren’t synonymous — you can load Bourbon into Compass. In this article, I’m not going to delve into either of these mixin libraries. Instead, I’m going to explore the frameworking capabilities of Compass, encourage you to create your own personal framework or tool, and show you how to share what you’ve made as a Compass extension.

But before going into the technical side of things, let’s talk about retaining knowledge. Those of us who work on the web learn and draw inspiration from multiple sources. Blog posts, conferences, design books — information is coming at us faster than we can digest it. How can we trust ourselves to remember it all? And even if we can remember a bit of CSS or a design technique, how are we supposed to remember exactly how to implement a more complicated technique without going back and looking it up?

That’s where frameworks come in. Frameworks are libraries of knowledge that can be shared and implemented easily. When I share my framework with my team or with the world, they immediately have access to all of the tools and techniques contained therein. As others add to this framework, I immediately have access to their knowledge. This makes a framework an ideal place to store, and build on, information.

Take a look at resets, for example. Resets are one of the most basic components web developers work with, and they are usually the first thing to load in most frameworks. Given all of the various browsers and elements involved, the research that goes into making resets is almost unfathomable. Getting everything styled consistently in a good reset is incredibly difficult because someone needs to cross-check myriad subtle variations. Resets often make assumptions about how you, the developer, want page margins and other styles to look. Doing the kind of research required to make everything consistent is not work that I particularly want to do. And so I gladly trust people like Eric Meyer and Nicolas Gallagher to handle it for me.

Whether it’s a reset, a grid, or form styles, these small components are often bundled into larger frameworks of knowledge. Fairly recently, massive frameworks like Bootstrap and Foundation (which solve just about every problem ever) and smaller frameworks like inuitcss (which solve more basic problems and leave the rest to us) have emerged. These are all fantastic libraries of information to draw on and they suit the needs of their creators exceedingly well. But these frameworks have a point of view and make assumptions about both design and implementation that might not work for everyone. The larger the framework, the more assumptions it makes. For example, just about every large framework uses a 12-column grid. 12-column grids are great and work for most people because they can be easily subdivided into nice, even units. But if my design requires a 10-column grid, a 12-column grid won’t suit my needs very well.

So the question arises: How can I execute on my unique project goals and implementation while not having to start from scratch? How can I build on information and assume knowledge from others without buying into all of their ideas? Maybe you like the structure of one framework but the grids in another — how can you win without compromising your point of view?

This makes a framework an ideal place to store, and build on, information

Have your cake.
Eat it, too.

Fortunately, we have package management tools like Bower and extendable frameworking tools like Compass. Compass components are usually distributed through RubyGems. (Don’t worry: no Ruby knowledge is required.) These tools offer us a huge amount of flexibility and control over the components we use on a project by allowing us to break them down into smaller modules and load them in as needed. Instead of having to use a massive framework, I can use a grid system or a typographic system I happen to like. If I need help with colors or forms, there is probably something I can pull in later to help me out. Instead of buying into every idea and solution someone might have, I can selectively use the ideas I like and simply ignore what doesn’t work for me.

I want to focus on Compass because it provides a fantastic system for using 3rd party extensions and also offers a framework for building a collection of tools you can use locally on all of your projects. It is tightly coupled with Sass to take advantage of some of the best CSS preprocessing capabilities. The tools you can import into Compass range from small components like a calculator that can help you generate values to use in your typography and button mixins to more massive frameworks. The smaller components remain a little more flexible and focused, but there is no end of stuff out there for you to import and use.

Roll your own framework

If you’re anything like me, you probably write your own mixins and snippets that you reuse on multiple projects. Maybe you copy and paste those mixins into new projects as you need them. It’s pretty easy to set up Compass to store these mixins and snippets in a centralized place so that your goodies will be available and up to date across all of your projects. This is called a Compass personal framework. Let’s say you have a directory of projects like this:

+ project-one
+ project-two

Perhaps you have a few styles to, say, style a button that you want to share between your two projects. Instead of copying and pasting the relevant code between your projects, you can create a new folder containing all of your button styles that both of your projects can reference.

- my-framework
- stylesheets
- _button.scss
+ project-one
+ project-two

Inside _button.scss, let’s write a bit of code for your button:

button {
background: red;
color: white;
border: none;
padding: .5em 1em;
&:hover {
background: lighten(red, 20%);
}
&:active {
background: darken(red, 20%);
}
}

Great! Now you have a button you can use across all of your projects. But how do you add it to a project? Easy: just add load "my-framework" to your Compass config.rb file and run compass watch project-one from your project directory. Now you can just import those styles anywhere in your project with @import "button";.

So now that you have made your awesome framework, let’s spin the button out into a Compass extension — because you want to share this component with the world, right? First, duplicate your my-framework directory and rename it cool-button. All you have to do now is add two files to your cool-button directory. One is a gemspec; the other is a simple ruby file with the same name as your extension in a folder called lib. Drop these files in, run through changing my-extension to the name of your extension, and you should be good to go. The last step is running gem build my-extension.gemspec and then gem push my-extension-0.0.1.gem, and people can download and install that gem to use in their own projects. You can also drop a Bower JSON file in to spin up a Bower version.

Phew! That may have been a lot to take in. To make things simpler, I consolidated everything into a metaframeworking github repo so that you can get started with some concrete working examples.

There is still so much more left out there to be explored and worked on

What inspires me

My first Compass extension was inspired by Tim Brown’s A List Apart article, More Meaningful Typography. The article was bursting with numbers and scales to help create more harmonious typographic arrangements. When I glanced through the text and saw all of those equations that I didn’t particularly want to do, it occurred to me that Sass might be able to handle them for me. I created a simple mixin that spit out a style with a value.

@mixin modular-scale($style, $value, $base: 16px, $scale: 1.62) {
@for $i from 1 through $value {
$base: $base * $scale;
}
#{$style}: $base;
}

This mixin simply creates a feedback loop that multiplies the numbers over and over for a set number of iterations. I found that it worked well, and I could use it in my projects, so I decided to publish it on GitHub for others. Almost immediately, people like Adam Stacoviak and Mason Wendell expressed interest in helping me out. One of the very first things I learned was that I could create my own functions in Sass; at the time, my mind was blown with all of this new knowledge.

@function modular-scale($value, $base: 16px, $scale: 1.62) {
@for $i from 1 through $value {
$base: $base * $scale;
}
@return $base;
}

We continued to add new features and really refined the mixin into an incredibly usable and powerful tool. There is still room for improvement, of course, and because the scope is so narrow it gives us the focus to make something great.

This combination of research and inspiration prompted me to dive into canonical works on page design and older grids, and resulted in the creation of Singularity. Sam Richard hopped on Singularity and is now a driving force behind it. I got tired of using color tools and created color schemer to add that functionality in Sass. nth-child support for IE in Toolkit had its beginnings in Michael Barrett’s incredible blog post on how it’s done. There is still so much more left out there to be explored and worked on.

Pass it on

I talked about knowledge a lot in this post because I think it is one of the most important things we trade in. It is just as important to learn new things as it is to teach, and by creating and sharing you teach others. One night, while discussing design education over pizza with Caren Litherland, she mused that a formal design education is perhaps becoming less necessary because we learn from our tools now. If we use a grid system, we learn about the design qualities of grids and how to construct them. If we use a modular scale calculator, we learn how to typeset better using modular scales. We all learn from using tools. We also learn from creating tools and pouring research into them. Next time you see something that inspires you and can’t wait to use it in your projects, build a tool around it and share it with the world.


Edited by Caren Litherland.

Additional input from Rob Wierzbowski, Андрей Михайлов, and Micah Godbolt.

Based on my talk at CSS Summit.