How to include CSS styles inline in Razor view?

后端 未结 3 993
清歌不尽
清歌不尽 2020-12-28 16:23

I am using Postal to 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

相关标签:
3条回答
  • 2020-12-28 16:52

    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):

    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;
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-28 17:01

    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:

    1. 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 view that 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;
              }
          }
      }
      
    2. Then in your Razor template, just go:

      @Html.EmbedCss("~/Content/EmailStyles.css")
      

      to embed your CSS text.

    3. Install the Premailer.Net package in your project; you can get it through NuGet.

    4. Render your Razor view into a string (I guess that's what Postal is for in your process? I believe RazorEngine can also do that).

    5. Run the string through Premailer.Net:

      PreMailer pm = new PreMailer();
      string premailedOutput = pm.MoveCssInline(htmlSource, false);
      
    6. Send as an e-mail!

    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 inlined because 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!

    0 讨论(0)
  • 2020-12-28 17:07

    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.

    e.g. http:www.example.com/css/EmailStyles.css

    0 讨论(0)
提交回复
热议问题