How to Build Responsive Email Templates That Don't Break
Responsive email templates fail because email HTML is not web HTML. Here is how to build templates with tables, inline CSS, and MJML that render everywhere.
Responsive email templates break because developers write them like web pages, and email is not the web. The rendering engines are older, stricter, and wildly inconsistent, and the worst of them (Outlook on Windows) uses Word to render HTML. If you build an email with flexbox, grid, and external stylesheets, it will look great in your browser and fall apart in half your users' inboxes. The way to build email that survives is to use the old, boring, reliable techniques: tables for layout, inline CSS, and a tool like MJML to generate them for you.
Why can't I just use normal HTML and CSS in email?
Because email clients do not run a modern browser. Gmail strips your <style> blocks in some contexts. Outlook desktop ignores most of CSS positioning and renders through Microsoft Word's engine, which does not know what flexbox is. Apple Mail is decent, then applies its own dark-mode color inversion. There is no shared standard everyone implements, so you are coding to the lowest common denominator, not the latest spec.
The practical consequences: layout must be done with nested tables, not divs and flexbox, because tables are the one thing every client renders consistently. Styles must be inlined onto elements, because external and even embedded styles get stripped. Widths need explicit pixel values with percentage fallbacks. It feels like coding in 2005 because, for email, it still is.
How do I make an email layout responsive?
Design mobile-first and let it scale up, because the majority of email opens are on phones. Use a single-column layout as your default; multi-column layouts are where email responsiveness goes to die on small screens. A single column that stacks naturally beats a clever grid that collapses into a mess.
Media queries do work in many clients (not all), so use them to adjust font sizes and stack columns on narrow screens, but treat them as progressive enhancement, not the foundation. The email must be readable without them, because the clients that ignore media queries are exactly the ones you cannot afford to break. Set explicit widths, cap your content around 600 pixels wide, and make tap targets big enough for a thumb.
Test the result across real clients before you trust it, because "looks right in my inbox" is not proof. This is a core part of how I test transactional emails before shipping: render across the client set your users actually open, with images off and dark mode on.
Should I use MJML or hand-write the tables?
Use MJML, or a similar framework. Hand-writing nested tables with inlined styles is error-prone, unreadable, and miserable to maintain. MJML lets you write clean, semantic components and compiles them down to the bulletproof table-and-inline-CSS mess that clients need. You get maintainable source and reliable output.
The bigger win is that MJML source lives in your repository. A template you can diff, review, and test in the pipeline is a template that does not break silently, which is why I keep transactional email templates in code rather than in a vendor's drag-and-drop editor. The visual editor produces markup you did not review and cannot test, and it ships changes straight to customers.
What breaks templates most often?
Dark mode and images. Dark mode inversion can turn your dark logo invisible on a now-dark background, or flip your carefully chosen text into something unreadable. Design for both light and dark, and test the inversion explicitly. For logos, a version that works on transparent or with an outline survives the flip.
Images breaking is the other big one. Many clients block images by default, so an email that is one big image shows the user a blank rectangle. Always use real text for anything that matters, set alt text on every image so the blocked state still communicates, and never put critical content (like a reset button or an order total) inside an image. Skipping merge-variable guards belongs here too: a null field that renders as raw template syntax is a rendering break, which is why handling merge variables in email templates safely is part of the same job.
Keep the template boring and it stays reliable
The temptation is to make email do what a web page does. Resist it. The most reliable transactional emails are simple: single column, real text, one clear action, tables underneath, inline styles, tested across clients. Boring renders everywhere. Clever renders in your inbox and breaks in Outlook.
Send the finished templates through a provider built for developers so your rendered, tested output ships the same way every time. Usermails is where I send application email, with the API and events to fit a real build pipeline. Use tables and inline CSS, generate them with MJML, design mobile-first for light and dark, and your responsive templates stop breaking the moment they leave your browser.