Compass

Sam Richard edited this page Jun 26, 2013 · 6 revisions

Compass is a CSS Authoring Framework for Sass, providing advanced tools built on top of Sass to make utilizing best practices and writing maintainable code easier to do. It provides three different things:

  • A standard for creating reusable SASS modules. Those modules are called Compass Extensions. Compass extensions are a set of externally maintained functionally, usually Sass but potentially including images, JavaScript, or even Ruby extensions to Sass, distributed as Ruby gems.
  • A compass Command Line Tool. The Command Line tool is used for working with Compass projects as well as acts as a wrapper for the currently installed Sass compiler. The most common command being compass watch which will watch for changes in a given Compass project and compile changes to that project's Sass (run from the same directory as config.rb)
  • A Compass Extension called Compass. Compass provides a collection of mixins and functions to use throughout a Compass project, some of the most useful being more advanced than is possible to write in vanilla Sass (these include many awesome image helpers).

Instructions for installing Compass across all major operating systems are available.

Setting Up Compass

Compass projects are slightly more involved than simple Sass projects as Compass needs to know more about your project to provide advanced functionality. Make sure you have Compass installed before continuing

Creating a Compass Project

You can create Compass projects in one of two ways; from the command line, either compass init inside the directory of an existing project, or compass create {project-name} to create a new project set up to use Compass. Doing either of these will create a sass and a stylesheets directory, as well as a config.rb file. The sass folder is the default folder to hold your Sass files, the stylesheets folder is the default folder for compiled CSS, and the config.rb file is the configuration file for Compass.

Config.rb

Your config.rb file is Compass' configuration file. The basic file has options for the different directories and some commented out options. The directories are as follows:

  • http_path: The path of this file when compared to your webroot
  • css_dir: The directory you'd like compiled CSS to be put in, relative to this file
  • sass_dir: The directory of your working Sass files, relative to this file
  • images_dir: The directory of your image files, relative to this file
  • javascripts_dir: The directory of your JavaScript files, relative to this file

In addition, you can add a fonts_dir folder. If you do not add one, Compass's default is a folder called fonts inside of your css_dir. The default settings include commented out relative_assets and line_comments settings, if you uncomment them they will make all paths passed through helper functions as relative paths instead of absolute paths (from http_path) or remove Compass' debugging CSS Comments, respectively. In addition, there is a commented out output_style setting that, if uncommented and set to one of the options provided, will change how your output CSS looks. The default for output_style is :expanded, the only other one I would suggest you look at is :compressed.

Compiling with Compass

There are two ways to have Compass compile your Sass through the command line, either through using compass watch from within the same directory as the config.rb file, or compass compile. The former will set Compass listening in the background for changes to your Sass files and recompiling your CSS on changes. The later will do a one-off compile of your Sass into CSS.

Using Compass Functions and Mixins

Gaining access to all of Compass' functions and mixins is as easy as adding @import "compass"; to the top of your working Sass file. All following Sass examples assume this.

CSS3 Mixins

Compass provides an array of mixins for various CSS3 properties which can be extremely useful. By using the Compass mixins instead of hand-coding your advanced properties, you can be ensured that all of the browser prefixes that are needed for a given property are in the correct order and are there so you don't fall in to bad practices like only targeting -webkit or -moz. Compass will also help to smooth out cross-browser differences in supported syntax, especially when it comes to something like CSS Gradients.

Can I Use

Before determining whether or not you need to use a CSS3 mixin from Compass, you should cross-check your intended browser support with what you're intending to accomplish using a tool like Can I use… with knowledge of intended fallbacks for graceful degradation. For instance, all target browsers IE9 and up, the current landscape of browser support suggests I can use border-radius without a prefix, and as such I don't need the Compass mixin for it, I can just write the property. CSS Gradients, however, still requires prefixing for a few browsers so using the Compass mixin is a good idea.

Gradients

Unlike the other CSS3 properties, gradients don't have a dedicated mixin. Instead, gradients can be made as part of the larger multiple background mixin. Both linear gradients (linear-gradient) and radial gradients (radial-gradient) have their own function to be used as part of the background mixin. There are two mixins you can use for gradients, either the @include background mixin that will write to the background: property, or the @include background-image mixin that will write to the background-image property. Use either where appropriate, and be sure to write a fallback for the property above the mixin call, if needed.

Images

One of Compass' strongest features are its array of image based mixins and functions. These range from simple path helpers to full image sprite generation. All paths, when used with image related functions, are relative paths from your images_dir in your config.rb file.

Image URL and Inline Images

When referencing images from your Sass files, instead of using the CSS url() syntax, you can instead use the image-url() syntax. This special function will automatically write the correct path to your images directory, plus whatever the relative path included. This allows you to potentially change your final image directory based on environment or switch from relative to absolute paths and have the correct paths always referenced. You can also use the inline-image() syntax instead to embed the image as a data URI directly into your output CSS. Take, for example, the following CSS:

#foo {
  background-image: url('../images/foo.png');
}

We can express this using image-url as follows:

# config.rb
#
images_dir: 'images'
#
relative_assets: true
#
#foo {
  background-image: image-url('foo.png');
}

We can express this using inline-image as follows:

#foo {
  background-image: inline-image('foo.png');
}

This would produce CSS that looks like the following:

#foo {
  background-image: url('data:image/jpeg;base64,/9j/4AAQSkZJRgAB…');
}

Image Dimensions

Compass comes with two functions to make sizing based on an image's size super easy, image-height() and image-width(). Both take relative paths to the image you'd like to know the dimensions of. They do not currently work with SVG images. Take, for example, the following CSS:

#foo {
  background-image: url('../images/foo.png');
  height: 150px;
  width: 78px;
}

We can express this using image dimension functions as follows:

#foo {
  background-image: image-url('foo.png');
  height: image-height('foo.png');
  width: image-width('foo.png');
}

Image Replacement

Compass comes with two helper functions for replacing text with an image. Simply call the @include replace-text or @include replace-text-with-dimensions mixins. Either of these will hide text in the give selector and add a background image, effectively replacing the text with the prescribed image. Take, for example, the following CSS:

#foo {
  text-indent: -119988px;
  overflow: hidden;
  text-align: left;
  background-image: url('../images/foo.jpg');
  background-repeat: no-repeat;
  background-position: 50% 50%;
}

We can express this using Compass image replacement as follows:

#foo {
  @include replace-text('foo.jpg');
}

Image Sprites

Compass includes a little bit of magic around Image Sprites, and by a little bit of magic, I mean never needing to hand-code an image sprite ever again. From within your defined images folder, create a folder of individual .png images you'd like to include in the given image sprite. Then, you use the import syntax to import all of the images to create the image sprite (@import "relative/path/to/folder/*.png";). Finally, a new mixin will be created called @include folder-sprite; that takes one input, the file name (without the extension). Each sprite also has a set of customization options you can set.Take, for example, the following example utilizing social media icons:

@import "social/*.png";

// Include the dimensions of each image with the called sprite.
$social-sprite-dimensions: true;

.twitter:before {
  @include social-sprite('twitter');
}

.facebook:before {
  @include social-sprite('facebook');
}

This would produce CSS that looks like the following:

.social-sprite, .twitter:before, .facebook:before {
  background-image: url('../images/social-s73b39b37ad.png');
  background-repeat: no-repeat;
}

.twitter:before {
  background-position: 0 -32px;
  height: 32px;
  width: 32px;
}

.facebook:before {
  background-position: 0 0;
  height: 32px;
  width: 32px;
}

This will also create a file social-s73b39b37ad.png one folder back from the folder we've imported. This is our image sprite.

Image Sprite States

When creating and using Image Sprites, there are special naming conventions to make your life easier. The CSS states :hover, :target, and :active are available through image naming conventions to allow you to manage them from the images themselves. To do so, simply append _hover, _target, or _active, respectively, to the file name you'd like to use for those states. Compass image sprites will then automagically create those states for you. Take, for example, the following Sass:

@import "nav/*.png";

.toggle {
  @include nav-sprite('hamburger');
}

This would produce CSS that looks like the following:

.nav-sprite, .toggle {
  background-image: url('../images/nav-s82f92d18cc.png');
  background-repeat: no-repeat;
}

.toggle {
  background-position: 0 0;
}

.toggle:hover, .toggle.toggle-hover {
  background-position: 0 -32px;
]

.toggle:target, .toggle.toggle-target {
  background-position: 0 -64px;
}

.toggle:active, .toggle.toggle-active {
  background-position: 0 -96px;
}

Extensions

Compass extensions, also called Compass plugins, are (usually) packaged gems that provide a set of functionality that you can use in your projects without needing to write it all yourself. Some very popular types of extensions include grid systems, CSS frameworks, and button styling. While quality and usefulness of any given extension will generally vary between use-case and author, Compass has a list of plugins. In addition, there is the Team Sass group that makes a large collection of high-quality Compass extensions and Sass related projects all following the general philosophy that you should have final control over your output CSS. Some examples of high-quality Compass extensions are as follows: