Sass up your Css with Sass - Syntactically Awesome Stylesheets

Oct 19, 2013 • val antonini

When I first started web development I used to dislike CSS. Looking back I see I only felt that way because I never bothered to learn it properly. It wasn't because I was lazy, I was just new to development and would focus most of my learning on the back end or be too busy learning front end technologies for thick clients such as Swing, WinForms and WPF (and some proprietary solutions too if they count). Now I really enjoy CSS and a quick look at codepen.io shows part of the reason why and that I'm not alone.

In saying this, I will be the first to concede that CSS has a lot of short comings. Enter SASS, Syntactically Awesome Stylesheets. The Sass website describes it best:

Sass is an extension of CSS3, adding nested rules, variables, mixins, selector inheritance, and more.

Variables

With Sass you can specify your colors in a variables and use them throughout your selectors:

$myTexture: url('/images/wood.png');
$myColour: #0000ff;

.header{
    background: $headerTexture;
    border-bottom-color: $myColour;
    border-bottom-width: 1px;
}

.footer{
    background: $headerTexture;
    border-top-color: $myColour;
    border-top-width: 1px;
}
And when its translated to CSS:
.header{
    background: url('/images/wood.png');
    border-bottom-color: #0000ff;
    border-bottom-width: 1px;
}

.footer{
    background: url('/images/wood.png');
    border-top-color: #0000ff;
    border-top-width: 1px;
}

Our markup now only needs 1 class and we still only need to modify one place to change our background image.

Nesting

This is great but we can still make it a little easier to read with nested rules:

$myTexture: url('/images/wood.png');
$myColour: #0000ff;

.header{
    background: $headerTexture;
    border-bottom: {
        color: $myColour;
        bottom-width: 1px;
    }
}

.footer{
    background: $headerTexture;
    border-top: {
        color: $myColour;
        bottom-width: 1px;
    }
}

This one may not be everyone's cup of tea but I think nesting makes for better readability. It translates to the same CSS as before but removes some of the duplication.

Functions

But wait, wouldn't it be nice if the border colour of our footer was a little bit lighter than the border colour of our header? No problem:

$myTexture: url('/images/wood.png');
$myColour: #0000ff;

.header{
    background: $headerTexture;
    border-bottom: {
        color: $myColour;
        bottom-width: 1px;
    }
}

.footer{
    background: $headerTexture;
    border-top: {
        color: lighten($myColour, 10%);
        bottom-width: 1px;
    }
}
.footer{
    background: $headerTexture;
    border-top-color: #3333ff;
    border-top-width: 1px;
}

This and so much more make Sass a wonderful extension to CSS. Head over to the official guide to see all the other features Sass provides. Oh, and the best part, because it's a superset of CSS, any valid CSSis valid SASS.

Getting up and running with Sass in MVC4

To get up and running with Sass in an MVC4 project, install BundleTransformer.SassAndScss via nuget. I prefer to use nuget as it ensure the appropriate handlers are added to the web.config.

Install-Package BundleTransformer.SassAndScss

If you don't have a BundleConfig.cs in your App_Start you will need to add one:

using System.Web.Optimization;
using BundleTransformer.Core.Transformers;

namespace MyWebApp
{
    public class BundleConfig
    {
        // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
        public static void RegisterBundles(BundleCollection bundles)
        {
            var scss = new Bundle("~/Content/MyWebApp").Include("~/Content/MyWebApp.scss");
            scss.Transforms.Add(new CssTransformer());

            bundles.Add(scss);
        }
    }
}

If you had to add the BundleConfig.cs don't forget the relevant entry in you Global.asax.cs:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);//don't forget me
}

Now just add the bundle to your Razor code:

@Styles.Render("~/Content/MyWebApp")

Be warned, SASS is addictive, once you've used it there is no going back.