Don’t use import-css directives when bundling

Consider the following code:

public ActionResult Index( )
{
  StyleBundle b = new StyleBundle( "~/b1");
  b.Include( "~/Content/base.css");
  BundleTable.Bundles.Add( b);
  return( View( "~/Src/b.cshtml"));
}

This Controller method creates a bundle and includes a css-file located at ~/Content/base.css and then returns the view. The css file looks like this :

@import "b2.css";
body
{
  font-family: Verdana;
  font-size: small;
}

This file imports another css file b2.css. This includes a style to render the ‘important’-div red:

#important
{
  color: #FF0000;
}

The last line in our C#-code renders file ~/Src/b.cshtml :

@System.Web.Optimization.Styles.Render( "~/b1")
<div id="important">This is important</div>

This file calls the Render from System.Web.Optimization.Styles. The purpose of the Optimization library is to minimize css-files and scripts when running a release build, saving you the hassle of manually creating minimized files. If you call on this Action in Visual Studio, optimisation is disabled because you’re running in debug-mode resulting in the following view :

result in debug mode

result in debug mode

You see a nice red sentence, just like expected. If you now publish a release build of this code, you’ll see the following :

release-mode

release-mode

The red sentence has turned black. What happened ? If you inspect the network traffic using F12-network, you see the following :

release-build traffic

release-build traffic

The imported css file is not found on the network, caused by optimisation failing to fetch the correct paths for imported css files.

Ergo : Don’t use bundling with imported css-files.

If in full control of your css-files, then don’t import css files using the ‘import’-directive. If you’re not in control of your css files (using jQuery, Openlayers, etc..) then don’t optimize your css files using bundling.

Notes:

  1. Optimisation failing isn’t noticed until you deploy a release build. Even if you run a release build local before deploying, a cached css maybe read thus fooling you. If you would inspect network traffic on a release build locally before deploying, you’d see it fails
  2. Optimization is turned on by the following line in Web.Config :
    <compilation debug="false" targetFramework="4.0"/>
    

    If you publish a release build, the attribute debug="false" is absent which results in ASP.Net using the default which is false:

    <compilation targetFramework="4.0"/>
    
  3. To quickly see if your optimized styles are rendering correct, you can also use the following statement in your C#-code :
    BundleTable.EnableOptimizations = true;
    
Posted in Bundling, Minification, MVC4, Visual Studio 2012 | Leave a comment