Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inline css when using the rails asset pipeline

Instead of having the page include a style tag with a link where to get the css from, which I could add to my view using rails' stylesheet_link_tag helper method, I want to have the css inline directly inside the page.

This is what I came up with so far:

%style(type="text/css")=File.read(physical_asset_path("email.css")) 

But I can't find any rails' helper method which gives me the physical path of an asset - physical_asset_path is just a dummy method invented by me.

Anybody knows how to get the physical path of an asset when using rails 3.2.x?

Is there an easier/ better way to get stylesheets - from css files inside the common rails assets paths - inline?

Use case: most email clients don't access external sources (like css, images) without user confirmation. So to get the emails properly displayed I need to embed the CSS inside the emails' HTML.

like image 843
gucki Avatar asked Apr 30 '12 16:04

gucki


People also ask

How do you Precompile an asset?

To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.

Is inline CSS styling advisable?

Inline styles, while they have a purpose, generally are not the best way to maintain your website. They go against every one of the best practices: Inline styles don't separate content from design: Inline styles are exactly the same as embedded font and other clunky design tags that modern developers rail against.

How does Rails asset pipeline work?

The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages and pre-processors such as CoffeeScript, Sass, and ERB.

Does inline CSS affect performance?

An inline CSS will load faster if the CSS content size downloads faster than your server would respond to an external CSS file request (considering DNS time, server latency, etc).


2 Answers

Rails.application.assets.find_asset('email').to_s will return the compiled asset as a string.

like image 118
Seth Bro Avatar answered Sep 23 '22 06:09

Seth Bro


Use premailer or premailer-rails3

https://github.com/fphilipe/premailer-rails3 or https://github.com/alexdunae/premailer

Joe's Nerd Party say:

We also used the Premailer gem to automatically inline the linked stylesheet in the email views. Our email layout looks something like:

%html   %head     = stylesheet_link_tag 'email'      %style{:type => "text/css"}       :sass         @media all and (max-width: 480px)           table#container             width: auto !important             max-width: 600px !important          ... and so on for the mobile code      %body        Email body here.       %table         Lots of tables. 

We include a stylesheet in the HTML. Premailer downloads it, processes it, and inserts the css rules inline in the HTML.

The @media rules need to be inline in the email layout, since Premailer can’t handle those being in a separate css file yet.

We use premailer-rails3 to integrate Premailer into Rails 3. Unfortunately, we found a bunch of bugs in premailer and premailer-rails3. Our forks of the projects are at https://github.com/joevandyk/premailer and https://github.com/joevandyk/premailer-rails3. The forks fix some encoding bugs, remove some weird css processing stuff done by premailer-rails3, allow premailer to not strip out embedded rules in the email layouts, and some other things.

We also found a bug in sass-rails, where you can’t embed image-urls in inline sass code. See https://github.com/rails/sass-rails/issues/71 Premailer-rails3 hooks into ActionMailer when the email actually being delivered, not just generated. When running tests, email is not actually sent, so the premailer-rails3 hooks don’t get ran during tests. I haven’t spent the time to see if it’s possible to get the premailer processing to run during tests, but that would be a nice thing to do.

Also, our forks on premailer-rails3 assume that you want premailer to go out and actually download the linked CSS files. It should be possible to use the Rails 3.1 asset pipeline to get the processed css without downloading it. A very special thanks goes to Jordan Isip who did the super annoying job of making sure the emails look great in all the different clients out there. Writing that CSS/HTML did not look fun.

Update:

Roadie appears to be a better option. Thanks to Seth Bro for pointing it out.

like image 36
Sully Avatar answered Sep 21 '22 06:09

Sully