MVC Bundling and CSS relative URLs
CssRewriteUrlTransform updates the CSS Url with absolute path, saying so if we use -
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css",new CssRewriteUrlTransform()));
and we have following CSS class in "site.css"
.Sandy
{
background-image: url("Images/Sandy.jpg");
border: 1px solid #c8c8c8;
border-radius:4px 4px 4px 4px;
box-shadow: 1px 1px 8px gray;
background-position:left;
background-size:contain;
-moz-background-size:contain;
-webkit-background-size:contain;
-o-background-size:contain;
background-repeat:no-repeat;
min-height:100px;
min-width:100px;
display:block;
}
and following folder structure -
-Web site Root
-Content
--site.css
--Images
---Sandy.jpg
Bundling will generate following CSS Url Path for "background-image" -
background-image: url("/Content/Images/Sandy.jpg");
And now if you hosting the website / web application as a website on web server above path will work,
because browser will send request for this resource using following Url because of leading '/'
http://<server>/content/images/sandy.jpg
but if you host the website as web application this will create problem. Because browser will still interpret this as absolute Url instead of relative and still send following request to fetch this resource -
http://<server>/content/images/sandy.jpg
So, the solution for this problem is using the relative Url even in CSS file and then remove the CssRewriteUrlTransform from the Bundle config as below -
background-image: url("Images/Sandy.jpg");
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
Asp.Net MVC - CSS Relative Paths vs. Bundles
Today I approach the same problem. And I found a solution (maybe not the most elegant one, but does not require you to rewrite all relative paths).
The whole point is to group styles, scripts, etc. into files with the same depth in folder hierarchy. When you use relative paths, you have to ensure that your bundle virtual path has the same depth as styles included in it.
On your example it could be something like this:
bundles.Add(new StyleBundle("~/css/name1/name2/bundle").Include(
"~/Content/themes/base/jquery.ui.dialog.css",
"~/Content/themes/base/jquery.ui.theme.css",
"~/Content/themes/base/jquery.ui.datepicker.css",
"~/Content/global/css/components.css",
"~/Content/global/css/plugins.css"
));
bundles.Add(new StyleBundle("~/css/name1/name2/name3/bundle").Include(
"~/Content/admin/layout/css/layout.css",
"~/Content/admin/layout/css/custom.css",
"~/Content/global/plugins/simple-line-icons/simple-line-icons.css"
));
bundles.Add(new StyleBundle("~/css/name1/name2/name3/name4/bundle").Include(
"~/Content/global/plugins/font-awesome/css/font-awesome.css",
"~/Content/global/plugins/bootstrap/css/bootstrap.css",
"~/Content/global/plugins/bootstrap-switch/css/bootstrap-switch.css",
"~/Content/admin/layout/css/themes/darkblue.css"
));
bundles.Add(new StyleBundle("~/css/name1/name2/name3/name4/name5/bundle").Include(
"~/Content/global/plugins/datatables/plugins/bootstrap/dataTables.bootstrap.css"
));
Unfortunately this looks awful. If you are able to change css files hierarchy I would suggest you to reorganize your solution, so you can easly and logicaly group these files.
Also, I would suggest you to set bundle optimization to true
BundleTable.EnableOptimizations = true
This will create bundles even if you are debuging your solution (it will make your output html consistent between debuging and publishing). It helps to find "relative paths" error before publishing to server.
mvc bundling and relative css image when website is deployed to an application
If there are no virtual directories involved the following code would do:
bundles.Add(new StyleBundle("~/bundles/css").Include(
"~/Content/css/*.css", new CssRewriteUrlTransform()));
but when VirtualDirectory is used CssRewriteUrlTransform will rewrite to Host instead of Host/VirtualDirectory. the solution is to derive CssRewriteUrlTransform which is fully discussed here: ASP.NET MVC4 Bundling with Twitter Bootstrap:
public class CssRewriteUrlTransformWrapper : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
}
}
Asp.net Error while trying to create a bundle - Only application relative URLs (~/url) are allowed
~Vendor/lib/animate/animate.min.css
is not a legal relative URL. It needs to be ~/Vendor/lib/animate/animate.min.css
Relative paths in CSS not valid when using MVC w/Bundles
See my answer at:
CSS/JS bundle in single file in mvc when publish with release option
It deals with this exact issue and the options you have to resolve it.
Relative paths and Bundle configuration
After some googling on the theme, it appears that the CssRewriteUrlTransform
class makes sure that the image urls work from the dynamic bundle css file, like this:
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/mainstyle.css",
"~/Content/bootstrap.css",
"~/Content/site.css")
.Include("~/Content/layout/style.css", new CssRewriteUrlTransform()));
If this does not help, but you however would like using bundling, divide your bundling in parts per folder. Put the folder path in the bundle "name", like this new StyleBundle("~[folder_path]/[any word, like 'css' ot whatever you like]")
:
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/mainstyle.css",
"~/Content/bootstrap.css",
"~/Content/site.css"));
bundles.Add(new StyleBundle("~/Content/layout/css").Include(
"~/Content/layout/style.css"));
Relative path transformations in CSS bundles
I believe this could be a bug with CssRewriteUrlTransform. It will resolve the host but not the virtual directory. This is what I use instead. It's just a wrapper class that allows the bundling process to resolve correctly.
public class CssRewriteUrlTransformWrapper : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
}
}
Usage...
bundles.Add(new StyleBundle("~/Content/css")
.Include("~/Content/Site.css", new CssRewriteUrlTransformWrapper()));
MVC Bundling and Minification: converts embedded images to to URL paths
Scrap that question. This is a known bug. Currently work around is to separate your css into embedded images and images via url.
Vote for these work-items: https://aspnetoptimization.codeplex.com/workitem/88 and https://aspnetoptimization.codeplex.com/workitem/108
Related Topics
Wonky Text Anti-Aliasing When Rotating with Webkit-Transform in Chrome
How Is Padding-Top as a Percentage Related to the Parent's Width
Can Flex Items Wrap in a Container with Dynamic Height
How to Use CSS to Position a Fixed Variable Height Header and a Scrollable Content Box
How to Select an Element Only When Inside Another Element
How to Change <Input Type="File"> Style
Switching CSS Classes Based on Screen Size
CSS Double Border with Outer Border Thicker Than Inner Border
How to Align Items in a <H:Panelgrid> to the Right
Apply Different CSS Stylesheet for Different Parts of the Same Web Page
Is @Page { Size:Landscape} Obsolete
How to Preserve Line Breaks in <Code> Block
Why on Safari the Transform Translate Doesn't Work Correctly
Inner Border Over Images with CSS
Media Query Grouping Instead of Multiple Scattered Media Queries That Match