David Jones

Extending SASS with Bourbon

If you are reading this you probably already know the benefits of using SASS to compile your CSS, so I'm not going to talk about that. What I am going to talk about is extending SASS further with a mixin library to make SASS even more powerful.

The mixin library I am going to discuss is Bourbon.

First of all lets look at the following code.

.circle {
    border-radius: 50%;
    height: 200px;
    width: 200px;
}

We are defining a class called circle that applies a height and width of 200px and a border-radius of 50%. The result is a circle. Now this code will work in most browsers but others will only work if we apply some vendor prefixes to the border-radius attribute. So lets update our class to include the necessary prefixes for backwards compatibility.

.circle {
    -webkit-border-radius: 50%;
       -moz-border-radius: 50%;
            border-radius: 50%;
    height: 200px;
    width: 200px;
}

We have solved the issue of incompatibility but we have created a new one. If we have another class that has a border-radius attribute we will be duplicating code. So the right thing to do is create a mixin for border-radius that handles adding all the prefixed attributes, eliminating the need for duplicated code.

@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
       -moz-border-radius: $radius;
            border-radius: $radius;
}

.circle {
    @include border-radius(50%);

    height: 200px;
    width: 200px;
}

We have now refactored this a little better and our code is more DRY. This is good but we are reinventing the wheel a little because Bourbon already provides this mixin for us to use.

Lets look at what else Bourbon provides and why its useful.

Pixel to em conversion

If you're a fan of the scalability and mobile friendliness of the em unit but you are more accustomed to working with pixels then you will enjoy the em() function. You can pass in a pixel value and it will convert it to the correct em unit value. You can also pass in a second parameter that will act as the parent value.

Here is an example straight from the documentation.

font-size: em(12);
font-size: em(12, 24);

Automatic vendor prefixes

It doesn't matter what you use, Bourbon will automatically apply the necessary vendor prefixes for you.

Easy font face declaration

Bourbon sees an end to the huge font face declaration blocks I used to use. Code goes from this.

@font-face {
  font-family: 'source-sans-pro';
  src: url('/fonts/source-sans-pro/source-sans-pro-regular.eot'); /* IE9 Compat Modes */
  src: url('/fonts/source-sans-pro/source-sans-pro-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('/fonts/source-sans-pro/source-sans-pro-regular.woff2') format('woff2'), /* Super Modern Browsers */
       url('/fonts/source-sans-pro/source-sans-pro-regular.woff') format('woff'), /* Pretty Modern Browsers */
}

To this.

@include font-face("source-sans-pro", "/fonts/source-sans-pro/source-sans-pro-regular", $file-formats: eot woff2 woff);

The retina image mixin

This is a very powerful mixin that generates the styles needed to apply a normal background image and a retina version of the background image. If we have an image called home-icon then we can use the following code to also add a retina background image with a size of 32 x 20 pixels.

span {
    @include retina-image(home-icon, 32px 20px);
}

This would generate the following CSS.

span {
  background-image: url(home-icon.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) {
    span {
        background-image: url(home-icon_2x.png);
        background-size: 32px 20px;
    }  
}

This is a very brief overview of what Bourbon is capable of. I would recommend having a read through the documentation and having a play around with it so you can discover the usefulness of this library first hand.