Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: What tools do you use to build HTML emails?
26 points by ohitsdom on June 5, 2015 | hide | past | favorite | 22 comments
I'm working on a side project that sends out daily/weekly email reports. I'm working in C# and using Mailgun[0] to send email, but I'm unsure of how to approach designing HTML email templates.

My concerns:

- Inconsistency across email clients.

- Is there a tool to inline CSS styles (since stylesheets are not allowed in gmail)?

- Displaying bar graphs. I thinkg my options are either doing this with tables/divs or to generate an image of the graph to avoid inconsistent formatting.

- The email reports will also be web pages. How do I avoid UI duplication?

I'd appreciate any suggestions and/or shared experience!

[0] https://mailgun.com

You need to write html like it's 1999. Use tables for layouts, avoid divs. Be very cautious with CSS. See: https://www.campaignmonitor.com/css/

For testing, either use Campaign Monitor for $5/test (across all the clients) -- https://www.campaignmonitor.com/

They repackage Litmus testing which is ~ $80/mo -- https://litmus.com/

To inline CSS there are lots of options, but this is a nice, free utility: http://putsmail.com/

Overall designing HTML emails sucks. It will take 10x more time than you think.

I had the questionable pleasure of developing our first HTML emails at work this week, and found the following links helpful. I ended up working from the reference provided in the first (A list apart article) link post https://github.com/alistapart/salted .


Which CSS is supported: https://www.campaignmonitor.com/css/

How to serve images: https://sendgrid.com/blog/embedding-images-emails-facts/

General guides and some templates:



Mailgun actually provided some free templates on their blog once. See this


Whoa, a ton of resources in that post. Thanks!

Awesome find - thanks.

In addition to the great recommendations, the grunt module https://www.npmjs.com/package/juice2 Helps a LOT when developing. Basically inlines all your external CSS into your selectors on build so you're not coding in an insanely messy HTML file.

Edit: Linked the NPM module, Here's the grunt one that uses juice. https://www.npmjs.com/package/grunt-email-builder

To inline CSS you can use the free tool from MailChimp:


As for templates MailChimp also offers hundreds of them through their GitHub:


Nice, I'll give the mailchimp tool a shot. I really just need to setup a handful of templates, so it being a manual tool isn't a problem at all.

I found an old broken link to free mailchimp templates, didn't think to check their Github! Appreciate it.

No problem. The inline tool has saved me countless hours though and is simple to use. Their templates are great for building blocks or also ready to go as they are.

I personally don't use HTML in emails. This is mostly fueled by a combination of my preference to receive text-only emails and my desire to follow the "Golden Rule".

That said, I can see why some folks would want HTML in emails, so it's sometimes worth making exceptions. To address your specific concerns:

> Inconsistency across email clients.

That's going to be a problem no matter what. My recommendation is to keep your HTML simple; the less complicated, the less of a chance for some MUA or other to screw it up.

> Is there a tool to inline CSS styles (since stylesheets are not allowed in gmail)?

Is there something in particular you're trying to achieve?

My approach would be to generate inline-styled HTML with templating (I use Ruby and Elixir mainly at the moment, so my approach would involve ERB or EEx (respectively); I don't know what equivalent(s) C# has). Like the above recommendation, though, keep your styling light; again, the fewer complexities, the fewer chances for the MUA to screw things up.

> Displaying bar graphs. I thinkg my options are either doing this with tables/divs or to generate an image of the graph to avoid inconsistent formatting.

Inline images are almost certainly your best bet here for maximum compatibility.

> The email reports will also be web pages. How do I avoid UI duplication?

By turning the email "reports" into emails with links to the actual (web page) report.

Part of your problem is that you're trying to treat email and web pages as equivalent media, when this isn't the case. Email is very much optimized for simple text-based communication; you should play to that strength instead of trying to mangle it into a role it's really not meant for.

Good info, thanks.

> By turning the email "reports" into emails with links to the actual (web page) report.

The type of users I'm targeting here would rather have the info delivered to the inbox then follow a link. If you're familiar with Mint, think something like their end-of-week financial summary.

Have you checked out Zurb's responsive email template? It might be something that you're looking for. -- http://zurb.com/playground/responsive-email-templates

The most mature and powerful Python tool for inlining CSS is https://github.com/peterbe/premailer

I started it but it's been actively maintained by over 30 coders over several active years.

C3.js[0] has a built in image exporter[1] you can use from the command line if you want to generate chart images programatically. I use something similar that I wrote just before this became part of C3 to generate the chart and upload it to S3. Then my email links to that image. Works very nicely!

0: http://c3js.org/

1: https://github.com/masayuki0812/c3/blob/14e92c54f9286bf28ff4...

We built our own library to manage transactional email, you define an HTML and Text template, a meta file and then the library inject your data and automatically inline css, it's for NodeJS but you might take some idea from it https://github.com/FGRibreau/node-transacemail

React... no really.

Write yourself some helper functions to generate placeholders for your backend language that's actually going to send the email, eg. $('varname') would translate to <?= $varname ?> $.if(..condition..) etc. Load them into global space to save yourself the trouble since you're going to write a lot of components.

You'll also a need a means of outputting raw html (note how placeholders have a lot of unsafe characters; react hates those) Just create a function that given a string as code, outputs <raw dangerouslySetInnerHTML={{_html: code }}/> After you compile the code with React.renderToStaticMarkup strip out any <raw> and </raw> tags from the resulting string and you're in business.

Since you're compiling to your native backend templating system you don't need to worry about keeping a node server going or anything; you just build once and it's done.

Using React (and javascript in general) has some key advantages,

1. you are using components, so you only need to write your garbage table code once and you can use the components to design your emails

2. you can run the same components though multiple configurations; one configuration might generate a template for html emails, another might generate the non-html emails, you just make the components smart in what they output... sadly with the advent of smart watches you're going to have to be sending both, enjoy.

3. you can leverage npm modules; for example the module inline-css will inline css from a css file; so you don't have to do it yourself by hand or rely on copy/pasting back and forth to some site

4. you can run your css though postcss and other compilers for all sorts of backwards compible goodness; including let you know how you've accidentally written such sophisticated code as "background" instead of "background-color" <.<

5. you can pipeline any other junk you have too; push your images to a cdn etc;

6. others, who are not so wise in the table-fu of '99 can dable in creating new emails easily; they just need to use only use existing components and everything (should) be fine most of the time

7. you can share your table-filth with others easily, yey?!


The biggest headache with emails is not the code involved so much as the time it takes to make the damn things. If you do it with out assistance by hand, what would be a 30min job if built as part of a page, is equivalent in "email dev time" to 1 day easily (don't forget your email client is not the only email client! you have to cater to such wonderful things as Outlook which is under the hood Microsoft Office! of all things). Not the greatest ratio time wise. So no matter how crazy or convoluted the method, I very highly recommend, you do anything in your power to do it any other way then code it 100% by hand.

No specific tools, but addressing a few points you and others raise:

Provide a text-only option. It's backwards-compatible, and while the old-timer argument carries weight (console mail client support), many mobile devices offer what's little better than a console-equivalent email experience.

If you generate links, make them short. I'd recommend fewer than 40 characters, fewer than 20 if you can. They travel far better.

Email isn't the Web. Clients differ, and ultimately HTML is not universally supported. You're relying on an opt-in preference, which is to say, you're relying on a self-selected community which will progressively reinforce your initial biases toward content presentation regardless of its validity. Beware that.

My favourite illustration of this is the "Six o'clock on Tuesdays Club meeting time prefernce question". If you ask a group of people in a club meeting at 6:00 pm on Tuesdays what time they prefer to meet -- it will strongly tend to be "6:00 pm on Tuesday", as you've already self-selected for those who prefer and can accomodate that option.

Email clients are inconsistent. Web clients are inconsistent. Fucking text editors are inconsistent (character support, font support, kerning, foreground / background colors, ...). Basically: fucking deal with it.

I'd avoid use of inline CSS entirely -- the less explicit layout you perform the better and more future-proof you are. Limit formatting to bold and italics _only_, and realize that _that_ may not get conveyed reliably. Numeric and bulleted lists should be explicit, not HTML entities. Basically: pre-render absolutely everything if possible. Don't use tables for layout, I'd be leery about them even for tabular data presentation.

Especially: avoid use of contrasting text colors to convey meaning, they're frequently stripped from generated output, e.g., by Mobile email clients.

Graphs: include images. For now, PNG is preferred (best rendering of line graphics), though modestly compressed JPG will occupy less space. Keep an eye on SVG support though. It's an _excellent_ format for rendering data visualization (though you'll absolutely want to down-sample large datasets), and there are libraries which support graphics creation. Client support is still developing, but should be widespread within a few years. All current major desktop clients provide decent support. Legacy browsers and other HTML-enabled tools, not so much.

Email / Web UI duplication: as above for email, that's a fact of life. Fucking deal with it.

Though I generally dislike PDFs, if you're preparing reports to be delivered to users, dropping a PDF or link to same is probably your best bet. Many browsers will now present these natively, many mobile devices (though not all) have some level of PDF support.

If you do this, I strongly recommend:

1. Use generator tools which create the smallest possible PDF possible. Many bloat output to a staggering degree. Bandwidth, mailbox size limitations, and other factors all favor _small_ attachments, still.

2. Landscape layouts. That's generally preferable for desktop viewing. While mobile devices are frequently presented portrait, it's far easier to perform a 90° transform on a Smartphone or tablet than a laptop or desktop monitor.

3. Put the executive summary and highlights in the email itself, detail in the reports.

There are a few alternative forms of delivery you might consider, among them RSS, and ePub or other eBook formats (far more flexible presentation, especialy on mobile). My read is that these aren't universally acceptable, but choosing a tool or tools which supports these and offering the option(s) to users might help clarify your future direction.

Email should not contain HTML. Not all mailtools are web browsers.

More specifically, emails and web pages serve different purposes, and trying to coopt the former to serve the purpose of the latter will lead to nothing but pain.

These customers would be opting-in for the HTML emails. They are not tech-savy customers, they just want the full info delivered to their inbox formatted nicely. I get that some people don't want HTML emails, but that's not what's happening here.

Not all web browsers support CSS, but that doesn't mean that web pages shouldn't contain CSS.

Applications are open for YC Summer 2021

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact