Anton Chisliuk · AI Marketing Ops
Anton Chisliuk
AI Marketing Ops

Marketing Automation and Agents

HTML Email Templates: Practical Getting Started Guide

Build HTML email templates that actually ship: cross-client safe code, MJML vs hand-code, Outlook fixes, testing, CRM integration, and governance. Operator playbook inside.

12 min readWritten by: Anton ChisliukMiddle of funnel

You don’t need a 40-page brand deck to send high-performing emails. You need a flexible HTML template system that renders cleanly in Outlook, scales across campaigns, and plugs into your CRM and automation. This guide shows you the operator way to build HTML email templates that ship fast, look consistent, and hit the inbox.

What “Good” Looks Like for HTML Email Templates

Good email templates are boring in the best way: predictable structure, minimal surprises, and strong performance. The goal isn’t to win design awards; it’s to communicate clearly and convert. You want a system that any marketer can use without filing a ticket to design every time they need a new module.

“Good” starts with cross-client reliability. Gmail, Apple Mail, Outlook (desktop, Mac, web — all different), Yahoo: your HTML needs to survive all of them. That means table-based layouts, inline CSS, and guardrails on imagery and fonts. It’s not glamorous. It works.

Finally, good templates tie back to your CRM and automation. Personalization tokens should render without breaking the layout. UTMs should be consistent and captured in the CRM. If a marketing leader can view a campaign and see delivery, clicks, pipeline, and revenue attribution, your template system is doing its job.

Choosing Your Approach: Hand-Coded, MJML, or ESP Builders

You have three practical paths to production: hand-coded HTML, a framework like MJML, or your email service provider’s drag-and-drop builder. Each has tradeoffs across speed, control, and long-term maintainability.

Hand-coded HTML gives you full control over every pixel and every fallback. It’s ideal for teams with in-house email dev skills or strict brand demands. The cost: slower iteration and more testing effort. If you build once and reuse for months with small changes, hand code is solid.

MJML compiles into robust HTML that handles many cross-client quirks for you. It’s fast to prototype modules and keep a consistent design system, especially across teams. The cost: extra compile step and the occasional need to tweak the compiled HTML for Outlook edge cases.

When hand-coding wins

Go hand-coded if you need pixel-perfect control, heavy conditional content, or complex layout logic (e.g., insurance, fintech, or marketplaces with transactional emails). You can build hybrid/fluid layouts, add VML fallbacks for Outlook, and keep HTML tight (great for deliverability and load time).

Hand code also shines when your ESP’s builder introduces markup bloat or strips attributes you rely on. If your team knows email HTML, you’ll spend less time fighting the builder and more time shipping.

Finally, highly regulated sectors may require explicit control over every element, alt text, and legal copy. Hand coding keeps you compliant and auditable.

When MJML is the pragmatic path

MJML speeds up new module development, especially for teams without deep email dev expertise. The responsive grid, columns, and components (like buttons and images) compile into robust table-based HTML that behaves well across common clients.

Use MJML if you’re standardizing a design system across multiple brands or countries. One repo, many modules, consistent spacing and tokens. Designers iterate on MJML; marketing compiles and ships.

If Outlook-specific hacks are needed, you can either extend MJML or post-process the compiled HTML. For most marketing emails, MJML is “good enough” and very productive.

When to use ESP builder blocks

ESP builders (HubSpot, Mailchimp, SFMC Content Builder, Braze, etc.) are fast for non-technical users. They’re great for simple newsletters, announcements, and one-off promos. Builders also handle image hosting, tokens, and basic conditions.

The tradeoff is markup bloat, occasional rendering quirks, and lock-in. If your team is small and you prioritize speed over perfect code, builders are a safe starting point. Just define strict modules and naming so you don’t drift into Frankenstein templates.

For high-volume programs or when you need transportable, controlled HTML, graduate to hand code or MJML and import the final HTML into the ESP.

Design System for Email: Modules, Tokens, and Constraints

Think “design system,” not “one template.” A good email system is a library of modules your team can assemble: header, hero, intro text, 1–3 column content blocks, testimonial, feature grid, event card, secondary CTA, social/footer. Each module has rules.

Define tokens for spacing (8px scale), font sizes (16/18/20/24/28), colors (brand, neutral, accent), and radii. Keep your base width to 600–640px for reliable rendering. Lock in a default body size of 16px for readability and accessibility. Limit line length by constraining content width inside columns.

Document constraints per module. For example, “Hero image: 1200x600 source, crops to 600x300, alt text required, headline max 60 chars, subcopy max 180 chars, primary CTA only.” Constraints make the system resilient when different people build emails under pressure.

  • Core modules to include: header with logo and view-in-browser, hero with CTA, 1–2 column text-image blocks, feature grid (3×1), testimonial/quote, event/webinar card, resource card, simple footer with address/unsubscribe.
  • Optional: alert bar, “You might also like” content recommendation, secondary CTA, plain-text fallback variant.
  • Compliance: legal snippet, address, unsubscribe link in every marketing message.

Deliverability First: HTML That Lands in the Inbox

Templates don’t fix authentication or sender reputation, but they can avoid “spammy” signals. Keep HTML lean. No JavaScript. Avoid forms in email. Limit external CSS; inline everything. Use web-safe fonts or include safe fallbacks. Don’t hide content with display:none on large blocks; some clients flag it.

Use balanced image-to-text ratio. Relying on one giant image with text baked in is a spam trap and an accessibility fail. Provide descriptive alt text. Constrain images to their containers and define explicit width/height to prevent layout shift.

Add a real preheader (40–90 chars) and a clear plain-text version. Include a visible unsubscribe link and company address. Authentication (SPF/DKIM/DMARC) and a warmed, reputable sending domain are non-negotiable—that’s outside the template, but your HTML shouldn’t introduce new risks.

Responsive and Accessible Emails That Don’t Break in Outlook

Modern mobile clients are forgiving; Outlook isn’t. Embrace table-based, hybrid/fluid layouts. Use max-width containers with percentage-based columns for responsiveness. For background images in Outlook, use VML fallbacks or avoid backgrounds and place images as content.

Design for dark mode. Use transparent PNGs with enough contrast. Avoid pure black text on pure white backgrounds; choose slightly off-white (#FAFAFA) and dark gray (#111) to reduce inversion issues. Test buttons and icons against both light and dark.

Accessibility matters: 16px+ body text, 44px+ tap targets on mobile, sufficient color contrast (WCAG AA), semantic structure (headings as real text, not images), and informative alt text. Keep link text descriptive (“View pricing” beats “Click here”).

<!-- Bulletproof button with VML fallback -->
<!--[if mso]>
  <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" href="https://example.com" style="height:48px;v-text-anchor:middle;width:220px;" arcsize="10%" stroke="f" fillcolor="#2F6FED">
    <w:anchorlock/>
    <center style="color:#FFFFFF;font-family:Arial, sans-serif;font-size:16px;">Get Started</center>
  </v:roundrect>
<![endif]-->
<!--[if !mso]><!-- -->
  <a href="https://example.com" style="background-color:#2F6FED;border-radius:6px;color:#FFFFFF;display:inline-block;font-family:'Inter', Arial, sans-serif;font-size:16px;line-height:48px;text-align:center;text-decoration:none;width:220px;">Get Started</a>
<!--<![endif]-->

Start with a 600–640px container centered on a neutral background. Use a single wrapper table with 100% width, then a fixed-width inner table for content. Set a default font stack (“Inter, Arial, sans-serif”) and body color/spacing tokens inline.

Add the header: logo on the left, optional “view in browser” link on the right. Keep it tight (48–72px tall). Logos should be retina-ready (2x) and constrained with width and height attributes. Include alt text and a link to your site.

Layer in your core modules: hero with H1 and CTA, supporting copy block with body text, 1–2 column content blocks with image and text, optional testimonial or feature grid, then a footer with address, social links, and unsubscribe. Every module gets a comment block so non-devs can find and reuse them.

<!-- Wrapper -->
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#F6F8FB;">
  <tr>
    <td align="center">
      <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="640" style="width:640px;max-width:640px;background:#FFFFFF;">
        <!-- Header -->
        <tr>
          <td style="padding:20px 24px;">
            <img src="https://cdn.example.com/logo.png" alt="Brand" width="120" height="32" style="display:block;border:0;" />
          </td>
        </tr>
        <!-- Hero -->
        <tr>
          <td style="padding:0 24px 16px;">
            <h1 style="margin:0 0 8px 0;font-family:Arial,sans-serif;font-size:24px;line-height:32px;color:#111111;">Your headline here</h1>
            <p style="margin:0 0 16px 0;font-family:Arial,sans-serif;font-size:16px;line-height:24px;color:#444444;">Short intro copy that sets context.</p>
          </td>
        </tr>
        <!-- CTA -->
        <tr>
          <td align="left" style="padding:0 24px 24px;">
            <!-- include the bulletproof button here -->
          </td>
        </tr>
        <!-- Footer -->
        <tr>
          <td style="padding:24px;color:#6B7280;font-family:Arial,sans-serif;font-size:12px;line-height:18px;">
            123 Business St, City. <a href="#" style="color:#6B7280;">Unsubscribe</a>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

Inline your CSS. Even if your ESP supports embedded styles, some clients will strip or ignore them. Use a preprocessor or a build script to inline consistently so humans don’t do it by hand.

Finally, produce a “plain text” counterpart automatically from your source. Make sure your preheader is represented and that links are readable. Keep it legible; some filters weigh plain-text quality.

Testing Matrix: Clients, Devices, and Edge Cases

Don’t ship blind. Maintain a fixed testing matrix with your most important clients and devices. Run previews on common webmail (Gmail, Yahoo), mobile (Apple Mail iOS, Gmail Android), and desktop (Outlook versions, Apple Mail). Use rendering tools to catch differences and verify your fallbacks.

Edge cases to test: long subject lines and preheaders, missing images (turn images off), dark mode, very long link URLs, languages with longer words, and content blocks repeated multiple times. Check that your CTA remains visible and tappable across combinations.

Run a deliverability pre-check: validate links, confirm alt text, ensure the unsubscribe link is present, confirm the sending domain and from-address, and verify that tracking parameters are consistent with your analytics/CRM. Do a seed test for inbox vs. promotions if that’s a KPI for you.

Template Governance: Versions, Naming, and Rollout

Templates drift when nobody owns versioning. Give every base template and module a semantic version (e.g., base v1.3, modules v2.0). Store a changelog. If you’re in MJML, tag releases and compile distributable HTML per version. If you’re in hand code, keep a components folder and documented snippets.

Use a naming convention non-developers understand: “MKT-Base-v1.3,” “Module-FeatureGrid-v2.0,” “Module-Testimonial-v1.1.” In the ESP, prefix “DO NOT EDIT” on master templates and provide “Copy to Draft” variants. Lock permissions if your platform allows it.

Roll out changes in waves. Don’t flip everything at once before a big campaign. Select a low-risk send, compare metrics (CTOR, click map, rendering feedback), then promote the change. Sunset outdated modules to avoid partial adoption that increases maintenance overhead.

Integrating With CRM and Automation

Your template shouldn’t be a standalone design artifact; it’s part of a system. Define standard personalization tokens (first name, company, product tier) and test how they render in empty/null cases. Wrap tokens in conditional comments if your ESP allows (“Hi there” if first name missing).

Establish a UTM policy and bake it into buttons and primary links. For example: utm_source=email, utm_medium=campaign, utm_campaign=[slug], utm_content=[module/button]. That consistency makes campaign reporting reliable in analytics and the CRM. If you’re building lifecycle or onboarding sequences, store the campaign and content names in your automation so you can trace ROI by program.

If you need help connecting the email layer to deal stages, lead scoring, or lifecycle logic, this fits neatly into CRM/marketing ops. See how a proper CRM implementation makes your email metrics useful for sales and revenue, not just opens and clicks.

Operating Notes: Metrics That Actually Matter

Opens are noisy now due to Apple Mail Privacy Protection and other proxying. Track them, but treat them as directional. Focus on delivered rate, click-through rate (CTR), click-to-open rate (CTOR), conversion rate, and revenue per recipient. For lifecycle programs, monitor time to activation and progression between key milestones.

Instrument post-click behavior. UTMs should map into your CRM so you can attribute pipeline and revenue back to specific sends or programs. If you’re B2B, track influenced opportunities, meeting requests, and demo completions. If you’re e-commerce, track add-to-cart, checkout start, and purchase value. Tie this back to cohorts and lists, not just one-off blasts.

Finally, watch the cost side: production time per template, QA load, and change request volume. A robust template system lowers production hours and errors. If your team spends half their week restyling emails, the system is failing regardless of CTR.

Build vs. Buy: In-House, Agency, or Operator

Hiring in-house gives you control but adds overhead: recruiting, training, and managing a niche skill set (email HTML is its own discipline). It’s great if you send high volume across many brands and can keep an email developer busy full-time.

Agencies move quickly at the start but often hide implementation complexity behind decks. You pay the agency tax: account managers, layered approvals, and retainers indexed to “activity” not outcomes. For something as operational as templates, you want ownership and speed, not ceremony.

An operator model sits in the middle: a senior builder ships, measures, and iterates inside your stack. At Anton Chisliuk · AI Marketing Ops, the engagement is one operator building systems—from templates to automation to CRM—so you’re not introduced to a new team every quarter. We’ve scaled programs end-to-end (e.g., Cleverence from 0→80K organic visits/month and 0→2K inbound leads/month) by keeping strategy and build in the same hands. If you want the backstory and model details, read the about page.

Use comments to mark module boundaries and editing instructions. Non-devs move faster when the template tells them what to change and what to leave alone. Example: “Edit text only below; do not change padding values.”

Adopt a token file or snippet at the top of your source (even in HTML) that lists brand colors and spacing. When a rebrand happens, you have one place to modify. If you’re using MJML or a build step, centralize tokens in variables.

Keep assets organized in a single folder path with versioned filenames: hero-spring-2026@2x.jpg. Avoid linking assets from multiple CDNs unless you must; some clients throttle mixed content or flag it as suspicious.

Dark Mode, Images, and 120 DPI Gotchas

Dark mode flips assumptions. Transparent PNGs help icons survive inversion. Increase contrast on button text and add slight inner padding to retain shape. Avoid pure white backgrounds behind logos that look like boxes in dark mode.

Outlook on Windows uses 120 DPI scaling. If images look fuzzy or mis-sized, ensure you’re setting both width and height attributes and test 1.5x/2x assets. For background images, prefer content images with VML fallbacks if necessary.

Always define fallback colors for text and backgrounds inlined on the element, not just in parent containers. Some clients drop inherited styles.

Compliance and Data Hygiene Built In

Every marketing email needs an unsubscribe link, physical address, and a privacy path appropriate to your region (CAN-SPAM, GDPR, CASL). Make these part of the base template so they are never “forgotten.” Don’t hide unsubscribes behind images or tiny fonts; it hurts reputation and frustrates users.

For personalization and dynamic content, log what fields you rely on and create fallback values. Nothing kills trust like “Hi {FirstName}” in a hero. Consider a QA checklist where null and unusual characters are tested before each campaign.

Respect preferences beyond unsubscribes: category-level opt-outs (product updates vs. promotions), frequency caps, and regional quiet hours. Your automation should do the enforcement; your template just needs the correct links and tokens.

Cold Outbound vs. Marketing Templates

Don’t confuse transactional, marketing, and cold outbound. Cold outbound HTML should be simpler, closer to plain text, and as “human” as possible to avoid deliverability issues. Marketing templates can be more designed but still balanced. Transactional templates prioritize clarity and legal content with minimal decoration.

If you’re building a prospecting program, separate infrastructure, domains, and templates from your core marketing sends. Use different link tracking and stricter sending rules. Keep the cold templates lightweight and personalized with merge fields that have safe fallbacks.

For teams that need 600/day outreach infrastructure with safe warm-up and domain rotation, that’s a different playbook than the one in this guide. If that’s on your roadmap, see how professional email outbound systems are structured, then decide if you want both tracks under one operations owner.

A Simple Workflow That Keeps You Shipping

Adopt a weekly cadence: backlog grooming (new modules or tweaks), build, test, and ship. Keep a “pattern library” email that shows all modules with real content. It’s your one-stop QA artifact and onboarding doc for new marketers.

Measure template performance by module. Click maps are helpful but look beyond heat: does the feature grid drive more qualified traffic than the hero in lifecycle emails? Does removing the secondary CTA improve primary clicks? Treat modules like A/B testable components.

As your system matures, freeze the base and iterate modules behind feature flags (version tags). Roll forward with clear notes and retire underperforming blocks. Simplicity beats novelty 9 times out of 10.

Soft CTA: Get Templates Connected to Revenue

If you want a working template system tied to CRM, scoring, and automation (not just pretty emails), book a short Growth Audit. We map your current stack, identify failure points (rendering, data, or ops), and outline a 90-day build plan.

Conclusion

You don’t need a bigger team to fix email. You need a lean, documented template system that renders across clients, respects accessibility, ties into your CRM and automation, and is governed like any other product asset. Pick your approach (hand code, MJML, or builder), define modules and tokens, inline styles, test on a fixed matrix, and roll out with version control.

If you’re ready to connect templates to journeys, scoring, and multi-channel campaigns, see what’s included under our marketing automation build. The fastest wins appear when one owner is accountable for templates, data, and triggers.

Author: Anton Chisliuk — operator, not agency. Leads, sales, content, and systems—one senior operator.

FAQs

- Should I start with MJML or pure HTML?

If you have email dev expertise and strict brand needs, pure HTML gives maximum control. If you want speed and a safer starting point for non-devs, MJML compiles into reliable HTML and is usually faster to scale.

- What width should I use for my email template?

Use a fixed content width of 600–640px for maximum client compatibility. Center it inside a 100% wrapper. This balance looks good on desktop and scales down well on mobile.

- Do I need a plain-text version?

Yes. Generate a readable plain-text version for every send. It’s a deliverability signal and a fallback for clients that prefer or enforce text-only rendering.

- How do I make background images work in Outlook?

Outlook desktop needs VML fallbacks. Either use VML for “backgrounds” or avoid backgrounds altogether and place images as content within tables. Always provide a solid color fallback.

- What’s the best button approach for cross-client support?

Use a table-based “bulletproof” button with inline styles and a VML roundrect fallback for Outlook. Define width, line-height, background, border radius, and font inline.

- Are custom fonts safe in email?

Some clients support them, many don’t. Always define a robust fallback stack (e.g., Inter, Arial, sans-serif). Test heavily if you rely on brand fonts and ensure contrast still meets accessibility guidelines with fallbacks.

- How should I handle UTMs?

Standardize UTMs across templates and automate their insertion in primary CTAs. Map them into your analytics and CRM so you can attribute pipeline and revenue to specific sends and modules.

- What metrics should I trust post-Apple MPP?

Treat opens as directional. Prioritize delivered rate, CTR, CTOR, conversion rate, and revenue per recipient. For B2B, track influenced pipeline and meeting requests; for e-comm, track purchase rate and AOV.

- Can I reuse marketing templates for cold outbound?

Not recommended. Cold outbound should be closer to plain text for deliverability and authenticity. Separate infrastructure, domains, and templates from your marketing sends.

- How often should I update templates?

Review quarterly. If you version modules and measure by component, you’ll know which blocks to retire or refine. Don’t rebrand the whole system during peak campaign cycles.

Written by

Anton Chisliuk

Founder & Lead Operator · AI Marketing Operator

Anton Chisliuk is a GTM Engineer and Marketing Systems Architect. He built Cleverence's AI-native revenue OS (88 Make blueprints, MCP hub, 0→200K organic, 2.2K leads/mo) and now delivers outsourced GTM Engineering — CRM, automation, SEO, outbound — for growth-stage businesses via aimrktops.com.

About Anton →

Ready to fix this — for real?

Book a free Growth Audit. No sales deck — a 30-minute conversation about your pipeline, stack, and what to ship first.

HTML Email Templates: Practical Getting Started Guide