DEV Community

Cover image for Why Your Tailwind Email Breaks in Outlook (and How to Inline It Properly
Muhammad Iqbal
Muhammad Iqbal

Posted on

Why Your Tailwind Email Breaks in Outlook (and How to Inline It Properly

You build an email in Tailwind. It looks perfect in the browser, fine in Gmail, and then desktop Outlook turns it into a mess.

If you've been there, here's why it happens and a workflow that makes it less painful.

The core problem

Tailwind classes like px-6 or bg-blue-600 don't carry any styling themselves. They point at rules in a stylesheet. Email clients don't reliably load or honor that stylesheet, and each one renders HTML with its own engine:

  • Flexbox and grid are unreliable in key clients
  • Transforms, animations and advanced selectors often fail
  • rem units and CSS variables can behave inconsistently
  • Media queries work in some clients and are ignored in others

The one thing nearly everything respects is a style attribute on the element itself. That's what "inlining" gives you.

What inlining does

Illustrative example:

<!-- Before -->
<a href="#" class="bg-blue-600 text-white px-6 py-3 font-bold">Confirm email</a>

<!-- After -->
<a href="#" style="background-color:#2563eb;color:#ffffff;padding:12px 24px;font-weight:700;">Confirm email</a>
Enter fullscreen mode Exit fullscreen mode

Doing this by hand across a whole template is slow, and one missed declaration can break a section in a single client without you noticing.

The tricky parts

Responsive variants. sm: and md: need media queries, and inline styles can't contain those. The workable approach is to inline the static utilities and keep responsive rules in a <style> block. Design so the email still looks fine if those rules are ignored.

Units. Convert rem to px using a known root font size.

Layout. If a utility depends on flex or grid, plan on swapping it for a table-based structure.

Email size. Inlining repeats declarations, so HTML grows. Gmail clips messages over roughly 102 KB, which can hide your footer and unsubscribe link.

A workflow that works

  1. Write the template in Tailwind.
  2. Convert it to inline styles.
  3. Read the warnings and fix fragile bits.
  4. Check the output size.
  5. Test in real clients, especially Outlook.
  6. Keep the Tailwind file as your source and re-convert after every change. Don't hand-edit the inlined output.

Trying it with a browser-based converter

For step 2, I built a free converter at AabiTech: the Tailwind CSS to Email-Safe Inline Style Converter. It runs entirely in the browser, so your template isn't uploaded.

What it does:

  • Supports Tailwind v3 and v4, with an Auto option
  • Offers Conservative, Balanced and Modern Email modes
  • Inlines static utilities and keeps responsive rules in a style block
  • Reports unsupported classes instead of silently guessing
  • Warns about fragile features like flexbox, grid, transforms and animation
  • Shows size change and a Gmail 102 KB check
  • Accepts custom theme JSON and @theme variables, plus options for root font size, !important on responsive overrides, and Outlook-safe table hints

It doesn't promise identical rendering everywhere, and neither does any converter. Treat the warnings as a to-do list, then test in the clients your audience uses.

If the output is hard to read, run it through an HTML beautifier.

Pre-send checklist

  • [ ] No flex or grid in the layout
  • [ ] Warnings reviewed
  • [ ] Size comfortably under Gmail's clip limit
  • [ ] Responsive rules are enhancements, not requirements
  • [ ] Tested in Gmail, Outlook, Apple Mail and mobile
  • [ ] Dark mode checked

Over to you

What's the worst email client bug you've fought? Do you inline at build time, or use something like MJML or a framework instead? I'd like to hear what's working for your team.

Top comments (0)