About Us

Be Careful When Bundling Stylesheets in MVC 4

by Travis Ellis 20. August 2012 18:47

Microsoft released the newest version of the MVC framework as part of their Visual Studio 2012 release this week. One of the features of this release is the bundling and minification capabilities. Bundling allows you to combine many resources such as stylesheets and scripts so that fewer requests are made to the server. An example on using this feature is below:

public class BundleConfig {
    public static void RegisterBundles(BundleCollection bundles) {
        // combine all of the jquery ui scripts into one bundle
        bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                "~/Scripts/jquery-ui-{version}.js"));

        // combine all of the jquery ui scripts into one bundle
        bundles.Add(new StyleBundle("~/content/themes/base/jquery").Include(
                "~/Content/themes/base/jquery.ui.core.css",
                "~/Content/themes/base/jquery.ui.resizable.css",
                "~/Content/themes/base/jquery.ui.selectable.css",
                "~/Content/themes/base/jquery.ui.accordion.css",
                "~/Content/themes/base/jquery.ui.autocomplete.css",
                "~/Content/themes/base/jquery.ui.button.css",
                "~/Content/themes/base/jquery.ui.dialog.css",
                "~/Content/themes/base/jquery.ui.slider.css",
                "~/Content/themes/base/jquery.ui.tabs.css",
                "~/Content/themes/base/jquery.ui.datepicker.css",
                "~/Content/themes/base/jquery.ui.progressbar.css",
                “~/Content/themes/base/jquery.ui.theme.css"));
    }
}

The above code creates bundles for the jQuery UI scripts and stylesheets. In order to use them in your view you do the following:

@Scripts.Render("~/bundles/jqueryui")
@Styles.Render("~/content/themes/base/jquery")

One thing you might be tempted to do when bundling your stylesheets is use a shorter name for your bundle such as "~/css/jqueryui", but there is one thing you need to be aware of when you do this. It is common for stylesheets to include references to images relative to the stylesheet directory. For example, the default jQuery UI theme is installed in the ~/Content/themes/base/ directory. Inside of that directory is an images/ folder that contains many of the sprites that jQuery UI uses. If you create a CSS bundle called "~/css/jqueryui" then you might notice that none of the jQuery UI icons work any more. This is because the content is expected to be relative to the directory that the stylesheet is in. When creating the bundle as ~/css/jqueryui, the images are expected to be in ~/css/images.

Unless you are running with debug=”false”, you might not even notice the problem. This is because by default, when running with debug=”true”, the ASP.net runtime will still make separate requests for every resource in your bundle. When changing to debug=”false”, ASP.net will actually combine all of the files in your bundle and make a single request (per bundle). The request might look similar to:

<link href="/css/jqueryui?v=ps9Ga9601PrzNA2SK3sQXlYmNW3igUv5FOdOPWptyus1" rel="stylesheet"/>

Since the request is being made to /css/jqueryui, the server expects that any relative paths are going to be relative to the /css directory. To fix this, you need to make sure your CSS bundle names are similar to the physical directory structure of your application. When installing the jQuery UI nuget package, it will put your stylesheets in the directory /content/themes/base/ so you should name your bundle "~/content/themes/base/jqueryui" to make sure that everything works.