I'm on mobile so my apologies for brief response but I'll update later.
Read this
Long story short it had to do with relative path being fouled after bundling. But the good news is the latest bundle library resolves it.
Update
To fill in the blanks, essentially what's happening is that the CSS files have relative paths to resources (in this case an icon sprite). When in debug mode, the files are output separately to the page so the references are retained (/Content/bootstrap.css
with a reference to images/glyphicons-halflings.png
(making the full path /Content/images/glyphicons-halflings.png
). However, when debug is removed the files are bundled and the path is now relative to whatever virtual path you gave your bundle. In the case of above, you now originate from /bundles/maincss
which makes for an erroneous /bundles/maincss/images/glyphicons-halflings.png
path.
The good news is that this was a resolved bug and as of Microsoft.AspNet.Web.Optimization
v1.1.0 you now have CssRewriteUrlTransform
that will replace all relative paths (within the CSS files) with their absolute-pathed counterpart. This means that no matter what you call the bundle, the resources will still be resolved.
So, to fix the issue, you can simple do the following:
IItemTransform cssFixer = new CssRewriteUrlTransform();
bundles.Add(
new StyleBundle("~/bundles/maincss")
.Include("~/Content/bootstrap.css", cssFixer)
.Include("~/Content/bootstrap-responsive.css", cssFixer)
.Include("~/Content/my.css", cssFixer)
);
My only qualm is how ugly this looks when you want multiple files, so to solve this you can simplify it with an extension method:
/// <summary>
/// Includes the specified <paramref name="virtualPaths"/> within the bundle and attached the
/// <see cref="System.Web.Optimization.CssRewriteUrlTransform"/> item transformer to each item
/// automatically.
/// </summary>
/// <param name="bundle">The bundle.</param>
/// <param name="virtualPaths">The virtual paths.</param>
/// <returns>Bundle.</returns>
/// <exception cref="System.ArgumentException">Only available to StyleBundle;bundle</exception>
/// <exception cref="System.ArgumentNullException">virtualPaths;Cannot be null or empty</exception>
public static Bundle IncludeWithCssRewriteTransform(this Bundle bundle, params String[] virtualPaths)
{
if (!(bundle is StyleBundle))
{
throw new ArgumentException("Only available to StyleBundle", "bundle");
}
if (virtualPaths == null || virtualPaths.Length == 0)
{
throw new ArgumentNullException("virtualPaths", "Cannot be null or empty");
}
IItemTransform itemTransform = new CssRewriteUrlTransform();
foreach (String virtualPath in virtualPaths)
{
if (!String.IsNullOrWhiteSpace(virtualPath))
{
bundle.Include(virtualPath, itemTransform);
}
}
return bundle;
}
Which makes the above code a little cleaner. (Arguably I picked a long method name, but I like to keep the method names clear with regards to purpose)
bundles.Add(
new StyleBundle("~/bundles/maincss").IncludeWithCssRewriteTransform(
"~/Content/bootstrap.css",
"~/Content/bootstrap-responsive.css",
"~/Content/my.css"
)
);