How to Fix Outlook Table Spacing Issues
Fix Outlook table spacing issues caused by mso-table-lspace, cellspacing, and Word engine quirks in HTML email templates.
Eliminate phantom vertical gaps, collapsed borders, and misaligned cells in Outlook desktop clients by enforcing strict table resets and MSO-specific conditional directives. Modern web browsers use standard CSS box models, but Outlook relies on Microsoft Word's legacy rendering engine. This engine ignores standard margin resets on <td> elements and injects proprietary whitespace when modern layout techniques are applied. A foundational grasp of Mastering Email HTML & CSS is required to maintain deterministic layouts in enterprise transactional systems.
Root Cause: Word Engine Rendering Behavior
Outlook's rendering pipeline parses HTML through Word's layout engine, which applies a default 1pt horizontal padding to table cells and aggressively collapses vertical whitespace. It completely ignores margin properties on <td> and <tr> elements. When developers apply display: flex, display: grid, or inline-block fallbacks, the Word engine miscalculates line-height and baseline alignment, resulting in unpredictable 4–8px phantom gaps. This is why the responsive email layouts approach leans on ghost tables rather than CSS layout modes when Outlook is in scope. The engine also overrides standard border-collapse behavior unless explicitly forced via HTML attributes and MSO-specific CSS overrides.
Exact Table Reset Protocol
Enforce a strict baseline reset on every structural table. Do not rely on external stylesheets or inherited CSS for table spacing.
Baseline HTML Attributes:
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt;">
<tr>
<td style="line-height: 100%; font-size: 0; vertical-align: top;">
<!-- Content -->
</td>
</tr>
</table>
Critical Rules:
- Always declare
cellpadding="0" cellspacing="0"directly on the<table>tag. - Apply
border-collapse: collapse;inline. - Set
line-height: 100%;andfont-size: 0;on wrapper<td>elements to eliminate inherited text baseline spacing. - Never use
marginon table rows or cells. - Use padding on
<td>elements for spacing; avoid margins on block-level elements inside table cells.
Implementing MSO Conditional Directives
Isolate Outlook-specific overrides using VML-style conditional comments. This prevents modern clients from parsing proprietary mso- properties while forcing the Word engine to respect your spacing rules.
Production-Ready Conditional Block:
<!--[if mso]>
<style type="text/css">
table, td, th { border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
td { padding: 0; margin: 0; }
.outlook-spacer { height: 20px; line-height: 20px; font-size: 20px; display: block; }
</style>
<![endif]-->
Implementation Notes:
- Place the conditional block in the
<head>before any inline styles. - Use a
<td>with explicitheight,line-height, andfont-sizeall set to the same pixel value for vertical gaps in Outlook instead ofmarginorpadding. - For horizontal spacing, nest a secondary
<table>with explicitwidthattributes. - Verify that your CSS inliner does not strip or mangle
<!--[if mso]>syntax. Configure your build pipeline to preserve conditional comments.
Vertical spacer pattern:
<!-- Outlook-safe vertical spacer -->
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="height: 20px; line-height: 20px; font-size: 20px;"> </td>
</tr>
</table>
Transactional Pipeline Integration
Automated dispatch systems frequently break table spacing during template compilation. Implement strict validation and inlining rules to prevent runtime layout shifts.
Pipeline Configuration:
- Whitespace Stripping: Enable aggressive whitespace removal in your templating engine (Handlebars, Liquid, MJML), but exclude content inside
<pre>,<code>, and conditional comment blocks. - CSS Inlining: Use an inliner that respects
<!--[if mso]>blocks. Juice must be configured withpreserveMediaQueries: trueand should not strip conditional comments — check that yourjuiceversion and config do not setremoveComments: true. The mechanics of keeping these comments intact are covered in preserving media queries when inlining with Juice. - Dynamic Data Injection: Sanitize all injected strings. Unescaped HTML or line breaks in dynamic variables can force table cells to expand. Wrap dynamic content in
<span style="display: block;">or explicitly setword-break: break-word;on the parent<td>. - Error Handling: Implement pre-flight validation. If the compiled HTML contains
<td style="margin:">or missingcellpadding="0", trigger a build failure and route to a staging queue for manual review. Catch malformed table closures with regex validation before SMTP handoff.
Detailed debugging workflows for enterprise-scale deployments are documented in Outlook Rendering Fixes.
Validation & Deployment Checklist
Execute the following sequence before promoting templates to production SMTP dispatch.
Pre-Flight Validation:
- Run compiled HTML through W3C Validator (ignore
mso-warnings). - Verify all structural tables contain
cellpadding="0" cellspacing="0". - Confirm no
display: flexorgridproperties exist in the compiled output. - Ensure
<!--[if mso]>blocks are intact, unminified, and properly closed.
Cross-Client Rendering Tests:
- Litmus / Email on Acid: Test against Outlook 2016, 2019, 2021, and Microsoft 365 (Windows).
- Visual Diff: Compare rendered output against a baseline screenshot. Look specifically for 1–4px vertical gaps between rows.
- Dark Mode Check: Verify that explicit background colors on
<td>and<table>prevent OS-level inversion from altering cell spacing perception.
Deployment & Monitoring:
- Deploy to a 5% traffic segment.
- Monitor bounce/reject logs for malformed HTML errors.
- If spacing anomalies appear in production, immediately revert to the last validated commit and audit recent CSS inliner updates.
- Maintain a version-controlled template registry. Tag each release with client-specific rendering notes.
Variant: Outlook 365 vs Outlook 2016/2019 Spacing Differences
Although both render through Word, the desktop versions are not identical, and a fix verified only in one can fail in the other. Outlook 2016, 2019, and 2021 (the perpetual-license MSI/click-to-run builds) apply the legacy 1pt cell padding and the most aggressive line-height inheritance. Outlook 365 (the subscription build) shares the same engine but ships incremental rendering updates, so a template that looks tight in 365 can still show 2–4px gaps in 2016. The safe stance is to reset for the strictest build and verify across all of them.
<!-- Reset that holds across Outlook 2016/2019/2021 AND Outlook 365 (Win) -->
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%"
style="border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;mso-padding-alt:0;">
<tr>
<!-- Outlook 2016-2019: mso-line-height-rule:exactly stops 2-4px baseline expansion 365 hides -->
<td style="margin:0;padding:0;font-size:0;line-height:0;mso-line-height-rule:exactly;">
<img src="https://cdn.example.com/divider.png" width="600" height="1" alt="" style="display:block;border:0;">
</td>
</tr>
</table>
Two MSO properties matter most here. mso-padding-alt:0; neutralizes a padding behavior that surfaces in 2016/2019 but is often invisible in 365, and mso-line-height-rule:exactly forces the older builds to honor the declared line-height instead of expanding it to the font's natural leading. Always confirm the fix in an actual 2016 render, not just 365, because 365's newer build masks the bug your 2016 recipients will see.
Variant: Nested Tables and the Compounding-Gap Problem
Spacing defects compound with nesting depth. Each nested <table> reintroduces the default cellspacing and the inherited line-height of its parent cell, so a three-level structure can accumulate 12px or more of phantom whitespace that no single reset removes. The Word engine does not inherit your outer reset into nested tables — every table is treated independently.
<!-- Nested tables: EACH level needs its own reset or gaps stack in Outlook 2016-2021 -->
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%"
style="border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;">
<tr>
<td style="padding:0;font-size:0;line-height:0;">
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%"
style="border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;">
<tr>
<!-- Outlook 365: inner table re-adds cellspacing unless reset is repeated here, not inherited -->
<td style="padding:16px;font-size:15px;line-height:22px;mso-line-height-rule:exactly;color:#334155;">
Nested content with no compounded gap
</td>
</tr>
</table>
</td>
</tr>
</table>
The rule is mechanical: every <table> in the tree carries cellpadding="0" cellspacing="0" border="0" and border-collapse:collapse;mso-table-lspace/rspace:0pt, and every spacer or wrapper <td> sets font-size:0;line-height:0. Flatten the structure wherever possible — fewer nested tables means fewer places for the Word engine to inject spacing. Where deep nesting is unavoidable (complex multi-column digests), the hybrid scaffolding described in responsive email layouts keeps the desktop structure rigid while letting it collapse cleanly on mobile.
Variant: Image Gaps Inside Spacing-Sensitive Cells
A distinct but related symptom is the 3–4px gap beneath images inside table cells in Outlook. Images are inline elements by default and sit on the text baseline, so the descender space below the line appears as a gap. The fix is display:block on the image plus the font-size/line-height reset on its cell.
<!-- Image gap fix: display:block removes baseline descender space in Outlook 2016-2021 + Apple Mail -->
<td style="font-size:0;line-height:0;padding:0;">
<img src="https://cdn.example.com/banner.png" width="600" alt="Promotional banner"
style="display:block;border:0;outline:none;text-decoration:none;-ms-interpolation-mode:bicubic;">
</td>
The -ms-interpolation-mode:bicubic property additionally improves Outlook's image scaling quality when the rendered width differs from the source width, preventing the jagged resampling that often accompanies the gap bug. Note that this is purely an Outlook concern — Apple Mail, iOS Mail, and Gmail all already apply display:block semantics or smooth scaling, so the same markup is harmless there while it is essential for the Word engine.
A second image-related trap is the align attribute. Setting align="left" or align="right" on an image floats it in the Word engine and reintroduces surrounding whitespace that display:block was meant to remove. For spacing-sensitive layouts, drop the align attribute on images entirely and control position through the cell's align attribute and padding instead, so the reset stays in one predictable place.
Targeted Debugging Steps
When a gap persists after applying the resets, work through these named checks in order.
- Symptom: gap only in Outlook 2016, clean in 365 — Cause:
mso-line-height-rulemissing. Fix: addmso-line-height-rule:exactlyto every text cell and re-render in 2016. - Symptom: gap grows with each section — Cause: nested tables without per-level resets. Fix: apply
cellspacing="0"andfont-size:0on every nested table and wrapper cell. - Symptom: thin line under every image — Cause: image on text baseline. Fix:
display:blockon the<img>andfont-size:0;line-height:0on the cell. - Symptom: spacing appeared after a build change — Cause: inliner stripped or minified
<!--[if mso]>blocks. Fix: confirmremoveCommentsis off; see preserving media queries when inlining with Juice. - Symptom: horizontal gap between side-by-side cells — Cause: residual cellspacing or whitespace between cells. Fix:
cellspacing="0"on the table andmso-table-lspace/rspace:0pt.
Tightened Validation Checklist
Run this focused pass specifically for spacing before any wider QA.
- Every table in the tree carries
cellpadding="0" cellspacing="0" border="0". - Every text cell sets
mso-line-height-rule: exactlywith an explicit pixelline-height. - Every spacer/wrapper cell sets
font-size:0; line-height:0. - Every structural image sets
display:blockandborder:0. - Rendered in Outlook 2016 (not only 365) with no visible row, image, or column gaps.
<!--[if mso]>blocks survive the inliner unminified and balanced.- No
display:flex,grid, ormarginon any<td>/<tr>in the compiled output.
Related
- Outlook Rendering Fixes — the full set of Word-engine workarounds
- Preserving Media Queries When Inlining With Juice — keep MSO conditionals intact through the build
- Responsive Email Layouts — ghost-table hybrids that avoid CSS layout modes in Outlook
- Inline CSS Automation — automate the reset so cells never ship with stray margins
← Back to Outlook Rendering Fixes