Adding a LESS Stylesheet to an ASP.NET vNext Project

CSS is hard. Preprocessors like LESS and SASS make it less hard. In Visual Studio 2013 when you saved a LESS stylesheet, Visual Studio created the CSS and Minified versions for you. Not so in Visual Studio 2015 CTP 6. We are going to have to do some work. Fortunately, I wrote a prior post the did a lot of the scaffolding for us. Specifically, it set up the node package manager and grunt for us. In this article I will take a look at what it will take to enable the LESS preprocessor for my build process.

Let’s start with creating a pretty basic LESS file. I’ve created a wwwroot/site directory and then created a site.less file with the following contents:

html, body {
	width: 100%;
	height: 100%;
	margin: 0 !important;
	padding: 0 !important;

@import (less) "header.less";

That @import is a less directive to incorporate another file – header.less – which must also be processed by the preprocessor. It looks like this:

header {
	width: 100%;
	height: 50px;
	background-color: #666666;
	color: #F0F0F0;

I’ve also added some code into the ~/Layouts/PageLayout.cshtml:

<!DOCTYPE html>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="~/lib/bootstrap/css/bootstrap.css">
  <link rel="stylesheet" type="text/css" href="~/lib/bootstrap/css/bootstrap-theme.css">
  <link rel="stylesheet" type="text/css" href="~/site/site.css">
        <li id="nav-appstore"><span class="glyphicon glyphicon-th"></span></li>
        <li id="nav-notifications"><span class="glyphicon glyphicon-comment"></span></li>
        <li id="nav-search"><span class="glyphicon glyphicon-search"></span></li>


  <script src="~/lib/jQuery/js/jquery.js"></script>
  <script src="~/lib/bootstrap/js/bootstrap.js"></script>
  <script src="~/site/site.js"></script>

Note that addition of the site/site.css file – that will be my generated CSS file – it doesn’t exist yet. To do the hard work of converting the LESS file into a CSS file, I need to use a grunt task. Going to the grunt website, it looks like contrib-less is the plugin I want – 285,000 people can’t be wrong. Let’s take a look at the Grunt task configuration:

module.exports = function (grunt) {
    bower: { ... },
    less: {
      development: {
        files: {
          "wwwroot/site/site.css": "wwwroot/site/site.less"

  grunt.registerTask("before-build", ["bower:install"]);
  grunt.registerTask("after-build", []);
  grunt.registerTask("clean", []);
  grunt.registerTask("project-open", []);

  // The following line loads the grunt plugins.
  // This line needs to be at the end of this file.

I’ve collapsed the bower task for simplicity but it’s still there. Don’t delete it. Don’t forget to add the grunt-contrib-less to your package.json as well. You can now go to the Task Runner Explorer, expand Tasks, right-click on the less task and select Run. The site.css file should appear in the the wwwroot/site directory for you.

Now all you need to do is to include the less task in the build process. To do this, you alter the “before-build” task definition in the Gruntfile.js. You’ve already wired up this alias task when you configured Grunt the first time. Edit Gruntfile.js again and replace the registerTask for before-build with this:

  grunt.registerTask("before-build", ["bower:install", "less:development" ]);

You can now click that IIS Express button and check out your work. Visual Studio will do a build prior to starting IIS Express. In certain circumstances, you will need to explicitly do a build using F6. I ran into this a lot when I was developing LESS style sheets.

If you are starting from a Starter Web project instead of an Empty project, the grunt stuff is mostly set up for you, However, you are likely to require linking the Grunt task to the build binding in the Task Runner Explorer. In addition, your grunt alias task is called “default” instead of “before-build”. The concepts are pretty much the same though.