[Awesome Ruby Gem] Use premailer-rails to CSS styled emails by adding them to the style attribute

premailer-rails

premailer-rails is a drop in solution for styling HTML emails with CSS without having to do the hard work yourself.

Styling emails is not just a matter of linking to a stylesheet. Most clients, especially web clients, ignore linked stylesheets or <style> tags in the HTML. The workaround is to write all the CSS rules in the style attribute of each tag inside your email. This is a rather tedious and hard to maintain approach.

Premailer to the rescue! The great premailer gem applies all CSS rules to each matching HTML element by adding them to the style attribute. This allows you to keep HTML and CSS in separate files, just as you’re used to from web development, thus keeping your sanity.

This gem is an adapter for premailer to work with actionmailer out of the box. Actionmailer is the email framework used in Rails, which also works outside of Rails. Although premailer-rails has certain Rails specific features, it also works in the absence of Rails making it compatible with other frameworks such as sinatra.

How It Works

premailer-rails works with actionmailer by registering a delivery hook. This causes all emails that are delivered to be processed by premailer-rails. This means that by simply including premailer-rails in your Gemfile you’ll get styled emails without having to set anything up.

Whenever premailer-rails processes an email, it collects the URLs of all linked stylesheets (). Then, for each of these URLs, it tries to get the content through a couple of strategies. As long as a strategy does not return anything, the next one is used.

Note that the retrieved CSS is cached when the gem is running with Rails in production.

Installation

You can install it as a gem:

1
$ gem install premailer-rails

or add it into a Gemfile (Bundler):

1
2
3
4
5
# Gemfile

# GitHub - fphilipe/premailer-rails: CSS styled emails without the hassle.
# https://github.com/fphilipe/premailer-rails
gem 'premailer-rails', `1.11.1'

Then, run bundle install.

1
$ bundle install

Configuration

Premailer itself accepts a number of options. In order for premailer-rails to pass these options on to the underlying premailer instance, specify them as follows (in Rails you could do that in an initializer such as config/initializers/premailer_rails.rb):

1
Premailer::Rails.config.merge!(preserve_styles: true, remove_ids: true)

For a list of options, refer to the premailer documentation. The default configs are:

1
2
3
4
5
{
input_encoding: 'UTF-8',
generate_text_part: true,
strategies: [:filesystem, :asset_pipeline, :network]
}

If you don’t want to automatically generate a text part from the html part, set the config :generate_text_part to false.

Note that the options :with_html_string and :css_string are used internally by premailer-rails and thus will be overridden.

If you’re using this gem outside of Rails, you’ll need to call Premailer::Rails.register_interceptors manually in order for it to work. This is done ideally in some kind of initializer, depending on the framework you’re using.

premailer-rails reads all stylesheet <link> tags, inlines the linked CSS and removes the tags. If you wish to ignore a certain tag, e.g. one that links to external fonts such as Google Fonts, you can add a data-premailer="ignore" attribute.

Usages

premailer-rails processes all outgoing emails by default. If you wish to skip premailer for a certain email, simply set the :skip_premailer header:

1
2
3
4
5
6
7
class UserMailer < ActionMailer::Base
def welcome_email(user)
mail to: user.email,
subject: 'Welcome to My Awesome Site',
skip_premailer: true
end
end

Emails are only processed upon delivery, i.e. when calling #deliver on the email, or when previewing them in rails. If you wish to manually trigger the inlining, you can do so by calling the hook:

1
2
mail = SomeMailer.some_message(args)
Premailer::Rails::Hook.perform(mail)

This will modify the email in place, useful e.g. in tests.

References

[1] GitHub - fphilipe/premailer-rails: CSS styled emails without the hassle. - https://github.com/fphilipe/premailer-rails

[2] premailer-rails | RubyGems.org | your community gem host - https://rubygems.org/gems/premailer-rails/

[3] GitHub - premailer/premailer: Preflight for HTML email - https://github.com/premailer/premailer