Make ASP.NET bundling specify media=screen for CSS bundle
Solution 1
I've found a more elegant solution.
I'm using the Styles.RenderFormat(format, bundle)
.
I have a BundlesFormats
class with a property called PRINT
and I use it like so:
public class BundlesFormats
{
public const string PRINT = @"<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />";
}
And in the cshtml:
@Styles.RenderFormat(BundlesFormats.PRINT, "~/bundles/Content/print")
Solution 2
Well, it's an ugly hack, but hopefully the team will add a built-in way to do it in the next release.
This is how I solved it, maintaining the caching string and still being able to add the media attribute to the tag.
@{
var cssMediaBundleUrl = BundleTable.Bundles.ResolveBundleUrl("~/stylesheets/mediacss", true);
}
<link href="@cssMediaBundleUrl" rel="stylesheet" type="text/css" media="screen" />
Guess I can turn this into an Html helper, will do that later and edit.
Solution 3
Another option to solve this issue, without compromising the debug ability, could be:
public static IHtmlString Render(string path, IDictionary<string, object> htmlAttributes)
{
var attributes = BuildHtmlStringFrom(htmlAttributes);
#if DEBUG
var originalHtml = Styles.Render(path).ToHtmlString();
string tagsWithAttributes = originalHtml.Replace("/>", attributes + "/>");
return MvcHtmlString.Create(tagsWithAttributes);
#endif
string tagWithAttribute = string.Format(
"<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\"{1} />",
Styles.Url(path), attributes);
return MvcHtmlString.Create(tagWithAttribute);
}
What I'm doing is just appending the given html attributes to the end of the tags (on debug mode) or to the end of the only link tag (when minification/bundling are enabled).
The usage in views:
@Bundles.Render("~/css/print", new { media = "print" })
The rest of the code:
public static IHtmlString Render(string path, object htmlAttributes)
{
return Render(path, new RouteValueDictionary(htmlAttributes));
}
private static string BuildHtmlStringFrom(IEnumerable<KeyValuePair<string, object>> htmlAttributes)
{
var builder = new StringBuilder();
foreach (var attribute in htmlAttributes)
{
builder.AppendFormat(" {0}=\"{1}\"", attribute.Key, attribute.Value);
}
return builder.ToString();
}
I've wrote a blog post about this subject: http://danielcorreia.net/blog/quick-start-to-mvc4-bundling/
Solution 4
Unfortunately there isn't a great way to hook into how the tags are rendered currently, we thought about adding a hook so you could add your own method to render each script/style tag. It sounds like we do need to do that. Should be pretty simple to add, I'll create a work item to enable this scenario...
As a temporary workaround, if you are willing to lose the debug/release functionality that Styles.Render gives you, you can render a reference to the bundle using Styles.Url which would give you just the bundle url, you can embed that inside your own tag.
Solution 5
Why not just use @media print? Check out http://www.phpied.com/5-years-later-print-css-still-sucks/
Related videos on Youtube
GR7
Updated on July 09, 2022Comments
-
GR7 almost 2 years
I'm just trying out ASP.NET 4.5 bundling and minification, and ran into an issue.
I've got around 10 css files, of which 2 were originally referenced in the layout using the attribute media="screen".
Since the syntax for adding a css to the bundle does not let you specify that such attribute should be added (makes sense, since the attribute would apply for the whole bundle), I was hoping to see an overload of @Styles.Render that would allow me to specify html attributes, like in other Html helpers, but there is none.
There is an ugly solution, in which since I know the url of the bundle created, i could just craft the tag myself, but I'd lose the caching mechanism that is handled by ASP.NET by allowing it to render the tag itself.
Is there a way to do this, am I missing something? Or is this just an oversight of the design team?
-
Adam Tal about 11 yearsJust use @Styles.RenderFormat (look at my answer for more detailed information)
-
-
GR7 over 11 yearsHao, I'm guessing you're a member of the ASP.NET team? It's weird that other Html Helpers do have overloads to allow the developer to set html attributes and the Bundle renderer methods dont. I'm thinking of hacking the generated tag (which would include the caching string) and just add the media attribute myself, that way i'd still have the caching and i can add it..i just thought it's really weird that this escaped the team.
-
GR7 over 11 yearsfound a way to do it through the framework, although it's not nice. I'll post it in a bit
-
Hao Kung over 11 yearsYou can just do this: < link href="@Styles.Url("~/stylehseets/mediacss")" rel="stylesheet" type="text/css" media="screen" />
-
RickAndMSFT over 11 yearsYes, Hao is the lead dev at MSFT for the optimization framework.
-
maets almost 11 yearsJust a note: This solution currently requires the prerelease version of "Microsoft ASP.NET Web Optimization Framework". The stable version does not have the "RenderFormat"-method.
-
IvanL over 10 yearsThis is now part of the 1.1.0 release
-
drzaus over 10 yearsunless the blocking issue he refers to has been cleared up, this is a relevant point
-
Andrus over 10 years@GR7 After upgrading to VS 2013 Express For Web this start to produce 404 error. I posted it in stackoverflow.com/questions/20052278/… How to fix ?
-
GR7 over 10 years@Andrus, have you tried any of the alternatives that other people have posted? I haven't revisited this code yet, but will certainly do soon, hopefully.
-
Andrus over 10 yearsNo, I havent. Please confirm that your/Hao solution does not work in VS2013 then I start to look into other ways. In this case this should unmarked as answer
-
zacharydl over 9 yearsI like this method because I can include the print-only file in my main styles bundle.
-
zacharydl over 9 yearsTook me a minute to realize it can be done on one line: @Styles.RenderFormat("<link href=""{0}"" rel=""stylesheet"" type=""text/css"" media=""print"" />", "~/bundles/Content/print")
-
Flinkman almost 9 yearsI think this is the most elegant solution, IMO.
-
janv8000 almost 8 yearsWhat's the package version used here?
Microsoft.AspNet.Web.Optimization.1.1.3
does not contain a generic Add method -
SandRock almost 8 yearsWhere does those thing come from?
Add<T>()
andStylesheetBundle