For the last couple of years, I used Less to pre-process my stylesheets, but recently made the switch to Sass, which is even more powerful than Less. Here's how I organize and compile my Sass stylesheets in ASP.NET MVC applications with Visual Studio.
#Approaches to Pre-Process CSS Files
When you're using a CSS pre-processor to write your stylesheets, you need to compile those files at some point of time. After all, browsers only understand plain CSS and know nothing about Less or Sass. There are three conceptually different approaches for compiling a stylesheet with a CSS pre-processor:
- Dynamically compile the stylesheet on the server when the file is requested.
- Compile the stylesheets to static CSS files right after updating and saving them.
#Compiling Sass Stylesheets
While Visual Studio 2013 ships with an editor that provides syntax-highlighting, IntelliSense, formatting, outlining, and more, it doesn't include a Sass compiler. This means that you can create new
*.scss files and edit them with nice tooling support, but Visual Studio won't generate the compiled CSS files for you.
There's a great Visual Studio extension, though, the Mindscape Web Workbench, which does exactly that (and a lot more). It splits your Sass editor into two panes and directly shows you the resulting CSS on the right-hand side:
When you save a
*.scss file, the Web Workbench will automatically compile it and create a CSS file for you that's nested underneath the Sass file:
Let's now take a look at how to organize our stylesheets.
#Organizing Sass Stylesheets
When you have even a medium amount of Sass rules, you want to split them up into separate files. Each of those should only contain styles for one particular piece of functionality. Thanks to the
@import directive that comes with Sass, it's almost trivial to import rules from other referenced stylesheets:
Note that the imported
_Mixins.scss stylesheet has a leading underscore in the file name. That causes the the Web Workbench (and the Sass compiler in general) not to generate a standalone
Mixins.css file. This is desired behavior as
_Mixins.scss only contains a collection of mixins which are inlined into the Sass rules that include them.
I usually create the above mixins file and a
_Settings.scss which defines variables for accent colors, font families, etc. that are used in various places of my stylesheets. If the website uses custom web fonts, those are defined in a
_Fonts.scss file. Here's how a simplified
Styles folder could look like:
#Setting Up Bundling and Minification
Because we want to create web applications with great performance, our stylesheets should be bundled and minified in order to minimize HTTP requests and bytes sent over the wire. Using the
@import approach described above, the bundling part is a piece of cake: Just create one main Sass file and import all required stylesheets. I like to name it
It's very convenient that the Web Workbench understands Sass dependencies, which means that the
Bundled.scss file is recompiled automatically whenever one of its imported stylesheets changes. There's no need to invoke the compilation manually, so you can simply make a change to one of the dependent stylesheets, save it, and be done.
Bundled.scss file is the only stylesheet whose name doesn't start with an underscore, so the Sass compiler will create a CSS file for it. That resulting CSS file with all the required rules can then easily be used in conjunction with a style bundle from the
System.Web.Optimization bundling and minification framework:
var styleBundle = new StyleBundle("~/Client/Styles/Bundled") .Include("~/Client/Styles/Bundled.css"); BundleTable.Bundles.Add(styleBundle);
Finally, the bundle needs to be rendered in the Razor layout view:
<head> <!-- ... --> @Styles.Render("~/Client/Styles/Bundled") </head>
When running in debug mode, the stylesheet will be rendered without being minified, which facilitates diving into the CSS rules when debugging. In production, however, minification CSS is desired and will be performed.
And there you go! That's how I work with Sass in my ASP.NET MVC applications.