asp.net-mvc 如何在 Razor 视图中内嵌 CSS 样式?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14298604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to include CSS styles inline in Razor view?
提问by luksan
I am using Postalto render MVC Razor views and send them via email. I have a custom CSS that I have defined specifically for the email views. Currently I am including them as follows:
我正在使用Postal来呈现 MVC Razor 视图并通过电子邮件发送它们。我有一个专门为电子邮件视图定义的自定义 CSS。目前我将它们包括如下:
@Styles.Render("~/Content/EmailStyles.css")
However, this only includes the relative link to the stylesheet, which will not work in an email:
但是,这仅包括指向样式表的相对链接,这在电子邮件中不起作用:
<link href="/Content/EmailStyles.css" rel="stylesheet"/>
I want to include the stylesheet inline so that it functions properly in the email. What is the best way to render the contents of a file-based resource within an MVC view?
我想内联包含样式表,以便它在电子邮件中正常运行。在 MVC 视图中呈现基于文件的资源的内容的最佳方法是什么?
采纳答案by Stay Foolish
I guess you will need to have a custom helper for that. On top of my head, there is no such a method to render the css path including the absolute path of the website.
我想您需要为此拥有一个自定义助手。在我的头顶上,没有这样的方法来呈现包括网站绝对路径在内的 css 路径。
e.g. http:www.example.com/css/EmailStyles.css
例如 http:www.example.com/css/EmailStyles.css
回答by Paul d'Aoust
I had the same question myself, and came across Premailer.Net. It looks like the library you need. Here's what you'd have to do:
我自己也有同样的问题,并遇到了Premailer.Net。它看起来像你需要的图书馆。这是你必须做的:
Create an extension method to help you embed your CSS into your page; there's an answer on a question on how to embed HTML in a Razor viewthat should help you. I've modified it for embedding CSS:
public static class HtmlHelpers { public static MvcHtmlString EmbedCss(this HtmlHelper htmlHelper, string path) { // take a path that starts with "~" and map it to the filesystem. var cssFilePath = HttpContext.Current.Server.MapPath(path); // load the contents of that file try { var cssText = System.IO.File.ReadAllText(cssFilePath); var styleElement = new TagBuilder("style"); styleElement.InnerHtml = cssText; return MvcHtmlString.Create(styleElement.ToString()); } catch (Exception ex) { // return nothing if we can't read the file for any reason return null; } } }Then in your Razor template, just go:
@Html.EmbedCss("~/Content/EmailStyles.css")to embed your CSS text.
Install the Premailer.Net package in your project; you can get it through NuGet.
Render your Razor view into a string (I guess that's what Postal is for in your process? I believe RazorEnginecan also do that).
Run the string through Premailer.Net:
PreMailer pm = new PreMailer(); string premailedOutput = pm.MoveCssInline(htmlSource, false);Send as an e-mail!
创建一个扩展方法来帮助您将 CSS 嵌入到您的页面中;有一个关于如何在 Razor 视图中嵌入 HTML 的问题的答案,应该可以帮助您。我已经修改了它以嵌入 CSS:
public static class HtmlHelpers { public static MvcHtmlString EmbedCss(this HtmlHelper htmlHelper, string path) { // take a path that starts with "~" and map it to the filesystem. var cssFilePath = HttpContext.Current.Server.MapPath(path); // load the contents of that file try { var cssText = System.IO.File.ReadAllText(cssFilePath); var styleElement = new TagBuilder("style"); styleElement.InnerHtml = cssText; return MvcHtmlString.Create(styleElement.ToString()); } catch (Exception ex) { // return nothing if we can't read the file for any reason return null; } } }然后在你的 Razor 模板中,去:
@Html.EmbedCss("~/Content/EmailStyles.css")嵌入您的 CSS 文本。
在你的项目中安装 Premailer.Net 包;你可以通过 NuGet 获取它。
将你的 Razor 视图渲染成一个字符串(我猜这就是 Postal 在你的过程中的作用?我相信RazorEngine也可以做到这一点)。
通过 Premailer.Net 运行字符串:
PreMailer pm = new PreMailer(); string premailedOutput = pm.MoveCssInline(htmlSource, false);作为电子邮件发送!
I've been using this technique in production for a while now, and it seems to be working quite well.
我已经在生产中使用这种技术有一段时间了,它似乎工作得很好。
Edit: Remember that styles on pseudo-elements can't be inlinedbecause they don't exist in the markup. I've also noticed the odd little bug in Premailer.Net -- I think their specificity and cascade rules aren't perfectly conformant. Still, it's pretty good and it's one more piece of code I didn't have to write!
编辑:请记住,伪元素上的样式不能内联,因为它们不存在于标记中。我还注意到 Premailer.Net 中的一个奇怪的小错误——我认为它们的特异性和级联规则并不完全符合。尽管如此,它还是相当不错的,而且它是我不必编写的另一段代码!
回答by dprothero
Upvoted Paul d'Aoust's answer, but I found this version of his helper method to work a little better for me (wouldn't try to encode things like quotes in the CSS):
赞成 Paul d'Aoust 的回答,但我发现他的辅助方法的这个版本对我来说效果更好(不会尝试在 CSS 中对引号之类的内容进行编码):
public static class CssHelper
{
public static IHtmlString EmbedCss(this HtmlHelper htmlHelper, string path)
{
// take a path that starts with "~" and map it to the filesystem.
var cssFilePath = HttpContext.Current.Server.MapPath(path);
// load the contents of that file
try
{
var cssText = File.ReadAllText(cssFilePath);
return htmlHelper.Raw("<style>\n" + cssText + "\n</style>");
}
catch
{
// return nothing if we can't read the file for any reason
return null;
}
}
}

