5 Ways to Improve Your Sass with Bourbon

If you write a lot of CSS, there’s a good chance you’re already familiar with Sass. Sass is one of the best ways to preprocess your CSS so you get the advantage of cleaner, DRYer, more maintainable code. And Sass alone can get you pretty far.

But one of the best things about Sass is that it leaves room for third-party developers to create extensions that can accelerate your Sass experience even further. One of the lightest and most powerful tools I’ve come across to enhance Sass is Bourbon.

Bourbon is a library of Sass mixins, functions, and add-ons that pick up where the Sass preprocessor leaves off, to provide you with a wealth of convenient functionality that you’re sure to appreciate in your Sass workflow. If you’re not familiar with Bourbon, I’ve written a step-by-step introduction to installing Sass and Bourbon, which you can take a look at to get you started.

Once you have Bourbon installed, Here are a few of my favorite ways to take advantage of the Bourbon library in your daily Sass coding.

1. Font Formats

With all the different browsers, and the different font formats, a large chunk of code is needed to declare a new font face in your CSS. But font faces provide so much versatility when developing sites, whether you’re just adding a catchy headline font, or incorporating a versatile icon font that can save you tremendous bandwidth over individual bitmaps, while rendering vector-sharp images at different sizes.

In order to support all in-use browsers, you need to create font files in a variety of different formats, and then reference all of them in your CSS before you even start to use your font. The browsers will be smart enough to know which one you can use in that particular session, but you need to reference all of them to make your site robust. The CSS to invoke the font face you looks like this:

@font-face {
    font-family: My-Font;
    font-weight: normal;
    font-style: italic;
    src: url('/styles/fonts/myfont.eot');
    src: url('/styles/fonts/myfont.eot?#iefix') format('embedded-opentype'),
       url(/styles/fonts/myfont.woff') format('woff'),
       url('/styles/fonts/myfont.ttf') format('truetype'),
       url('/styles/fonts/myfont.svg##My-Font) format('svg');
}

All that just so that you can use the font you want for your headlines:

h1, h2, h3 {
    font-family: 'My-Font', sans-serif;
}

Bourbon provides a very convenient mixin for Sass that lets you define a new font family quickly and easily. As long as you use consistent naming for your font files, and upload them to your server in the same directory, Bourbon will take care of all of that repetitive CSS, and give you the same robust CSS you saw above with this simple bit of code:

@include font-face(My-Font, '/fonts/my_font/MyFont-Italic', normal, italic);

Now you can use ‘My-Font’ anywhere you want to in your CSS, and all the formats will be recognized automatically by all the appropriate browsers.

Bourbon also provides default variables for predefined font stacks that work well for standard web browsers using the fonts a user already has installed. These will help you create quick and robust font stacks that closely mimic the style of the preferred font, and degrade logically across different platforms.

The following Sass/Bourbon:

font-family: $helvetica;
font-family: $georgia;
font-family: $lucida-grande;
font-family: $monospace;
font-family: $verdana;

generates the following CSS font stacks automatically:

font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
font-family: Georgia, Cambria, "Times New Roman", Times, serif;
font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
font-family: "Bitstream Vera Sans Mono", Consolas, Courier, monospace;
font-family: Verdana, Geneva, sans-serif;

2. Form Inputs

The meat and potatoes of web development is control over form presentation. But adding styles that work consistently across multiple form elements usually means having to write out complex selectors that seem to go on forever.

For example:

input[type="email"], input[type="number"],
input[type="password"], input[type="search"],
input[type="tel"], input[type="text"],
input[type="url"], input[type="color"],
input[type="date"], input[type="datetime"],
input[type="datetime-local"], input[type="month"],
input[type="time"], input[type="week"] {
  color: #999;
}

Bourbon defines a set of very useful add-ons to make uniform form element selector styles easy to create and manage. The CSS above can be generated with the following bit of Bourbon-flavoured Sass:

#{$all-text-inputs} {
  color: #999;
}

A similar add-on exists to support button inputs. This code:

#{$all-button-inputs} {
  background: #f3f;
}

will produce this set of CSS selectors:

input[type="button"],
input[type="reset"],
input[type="submit"] {
  background: #f3f;
}

And if you want to control the :active and :hover states of these form elements, Bourbon’s got you covered there as well. Adding -active or -focus to the Bourbon add-ons above will generate just what you had in mind. For example, this code:

#{$all-text-inputs-hover} {
  color: #000;
}

will produce this CSS:

input[type="email"]:hover, input[type="number"]:hover,
input[type="password"]:hover, input[type="search"]:hover,
input[type="tel"]:hover, input[type="text"]:hover,
input[type="url"]:hover, input[type="color"]:hover,
input[type="date"]:hover, input[type="datetime"]:hover,
input[type="datetime-local"]:hover, input[type="month"]:hover,
input[type="time"]:hover, input[type="week"]:hover {
  color: black;
}

3. Unit Conversions

One thing that always takes time and brain juice is figuring out how to convert pixel values from images and fonts to match relative scaling values such as em or rem. While you can do the math every time, and update it as your values change, Bourbon does the work with some convenient conversion functions.

To start with, if you have a dimension in px, Bourbon can convert it directly to a flexible em value using a default base of 16px = 1em. The following code:

p {
  font-size: em(10);
}

will output the following CSS:

p {
  font-size: 0.625em;
}

If you want to calculate the em value based on a different scale instead of 16, you can pass the alternative value as a second optional parameter to the em() function:

p {
  font-size: em(10, 32);
}

will output the following CSS:

p {
  font-size: 0.3125em;
}

And if you prefer rem over em, to inherit from the base value regardless of the scale of the parent element, there’s a corresponding rem() function as well. This code:

p
  font-size: rem(10)

will output the following CSS:

p {
  font-size: 0.625rem;
}

There are several other conversions supported in Bourbon as well, including the soothing golden-ratio() function, which can come in handy when you want your layout or your font rhythm to resonate with the aesthetic wisdom of the ages.

4. Flexbox Support

The new hotness in CSS layout is flexbox, which allows you to define your layout elements and how they behave in ways that used to require cumbersome combinations of extra HTML and convoluted CSS. But flexbox has actually been around since 2009 in a variety of flavors.

Of course, to support all the different browsers and the ways they interpret the CSS for flexbox, you need to write a lot of browser-specific prefixes and cover fallback cases. Depending on how far back you want to offer support, writing CSS with flexbox can force you to create complex CSS that looks like this:

.container {
  display: -webkit-box;
  display: -moz-box;
  display: box;
  display: -webkit-flex;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  box-orient: vertical;
  -webkit-flex-direction: column;
  -moz-flex-direction: column;
  flex-direction: column;
  -ms-flex-direction: column;
  -webkit-box-align: center;
  -moz-box-align: center;
  box-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  -ms-align-items: center;
  -o-align-items: center;
  align-items: center;
  -ms-flex-align: center;
  -webkit-box-pack: justify;
  -moz-box-pack: justify;
  box-pack: justify;
  -webkit-justify-content: space-between;
  -moz-justify-content: space-between;
  -ms-justify-content: space-between;
  -o-justify-content: space-between;
  justify-content: space-between;
  -ms-flex-pack: justify; 
}

.container > .box {
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  box-flex: 1;
  -webkit-flex: 1;
  -moz-flex: 1;
  -ms-flex: 1;
  flex: 1;
}

Doesn’t that just look like a hand cramp waiting to happen? So if you need support in those older browsers, Bourbon can handle your flexbox syntax for you and generate all that CSS with just a few simple lines:

.container {
  @include display(flex);
  @include flex-direction(column);
  @include align-items(center);
  @include justify-content(space-between);
}

.container > .box {
  @include flex(1);
}

Bourbon includes support for a pretty complete set of flexbox options. And as long as you keep your Bourbon installation updated, you can expect it to adapt as the browsers improve their support for flexbox layouts.

5. Retina Images

Now that our visitors expect us to support both standard and high-dpi displays, we have to get fancy about which images we display to different devices, to preserve bandwidth but still provide the best visual experience to all of our users.

One approach involves using CSS media queries and defining the min-device-pixel-ratio to load a different background image depending on whether or not the display on a particular device can support higher resolutions. The CSS to make this work looks something like this:

.hero {
  background-image: url(hero-background.png);
}

@media only screen and (-webkit-min-device-pixel-ratio: 1.3),
       only screen and (min--moz-device-pixel-ratio: 1.3),
       only screen and (-o-min-device-pixel-ratio: 1.3 / 1),
       only screen and (min-resolution: 125dpi),
       only screen and (min-resolution: 1.3dppx) {

    .hero {
      background-image: url(hero-background_2x.png);
      background-size: 400px 300px; 
    }

}

You can see that there’s a lot of redundancy in there, especially if you’re consistent about how you name and store your background image file. Taking advantage of this consistency, Bourbon allows you to add all that CSS using this simple one-liner:

.hero {
  @include retina-image(hero-background, 400px 300px, png);
}

The extension parameter is optional if you’re using a PNG image, as Bourbon defaults to PNG. You can also customize this command with other optional parameters such as a specific retina image and suffix.

Get Started Today

With all this useful functionality built-in, and dozens of other features on top of that, it’s hard to imagine going back to writing plain Sass, let alone plain CSS, without Bourbon. I hope you’ll be encouraged to give it a try, and let me know what your favorite Bourbon features are!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://viii.in Vinay Raghu

    Very cool. Have always wanted to get into bourbon but never had the time to invest in learning. Especially loved #{$all-text-inputs} makes my code so much cleaner !

  • Donald Allen

    Bourbon + Neat are a killer combo. Forces you to think semantically. You can pretty much avoid using classes completely. Makes for a cleaner Sass codebase and a much smaller output CSS file.

  • Bruno Seixas

    Great! I wasnt aware of Bourbon.
    Really liked the flexbox mixin.

  • http://designerandgeek.com/ Designer and Geek

    Agreed! Very hard to grasp how to do Neat “the correct way” in practice.

  • silvenon

    Autoprefixer is a much better choice for flexbox, otherwise yes, Bourbon is pretty Neat (“Neat” is also their library :P).

    • http://www.josuevelazquez.com/ Miguel Josue Velazquez

      I use autoprefixer, and thinking on start using bourbon. So for flexbox you would code with no prefixes and after compiling execute autoprefixer?