LEARNING OBJECTIVES ⌵
- Master Microsoft Office (MSO) conditional comment syntax for targeting or hiding code from desktop Outlook.
- Understand and implement Ghost Tables to provide rigid table constraints to Outlook while serving fluid
divlayouts to modern clients. - Harness Vector Markup Language (VML) to render background images and rounded shapes inside the Microsoft Word rendering engine.
- Eliminate the notorious 120 DPI / 150% Windows display scaling bug using Office Document Settings XML.
📖 The Mental Model & Story (Intuitive Foundation)
Imagine you are shipping a physical product worldwide in a single standardized container. For 90% of your shipping destinations (modern ports with high-tech automated crane systems), the container is processed smoothly using modern hydraulic lifts.
However, for one critical legacy port (corporate enterprise desktop Outlook on Windows), all cargo must be hauled by a steam-powered locomotive with rigid railway track widths. If you send your modern cargo without specialized rail brackets, the cargo derails, flips over, and shatters into pieces.
Incoming HTML Payload
│
├──> Seen by Modern Clients (WebKit, Blink, Gecko):
│ Renders standard responsive <div> and fluid layout.
│
└──> Seen ONLY by Desktop Outlook (Microsoft Word Engine):
<!--[if mso]>
<table width="600" cellpadding="0" cellspacing="0"><tr><td>
<![endif]-->
(Rigid railway tracks lock Outlook into a strict 600px grid)
<!--[if mso]>
</td></tr></table>
<![endif]-->
MSO Conditional Comments are specialized conditional directives that Microsoft Office parsers execute while standard web browsers (and WebKit/Blink email clients) ignore them as ordinary HTML comments. By using MSO conditionals, you create a parallel universe inside your email: modern clients get modern fluid HTML, while desktop Outlook gets rigid, unbreakable tables and vector graphics.
Technical Deep Dive & Specifications
MSO Conditional Comment Syntax Grammar
There are two primary flavors of conditional comments: Downlevel-Hidden (visible ONLY to MSO) and Downlevel-Revealed (visible to EVERYTHING EXCEPT MSO).
1. TARGET ONLY OUTLOOK (Downlevel-Hidden):
<!--[if mso]>
<p>This markup is parsed ONLY by Microsoft Word / Outlook.</p>
<![endif]-->
2. HIDE FROM OUTLOOK (Downlevel-Revealed):
<!--[if !mso]><!-->
<p>This markup is visible to Apple Mail, Gmail, Web, but INVISIBLE to Outlook.</p>
<!--<![endif]-->
Version-Specific MSO Targeting:
Microsoft Outlook versions map to specific MSO version numbers:
| Outlook Version | MSO Version Code | Conditional Example |
|---|---|---|
| Outlook 2007 | mso 12 |
<!--[if mso 12]> |
| Outlook 2010 | mso 14 |
<!--[if mso 14]> |
| Outlook 2013 | mso 15 |
<!--[if mso 15]> |
| Outlook 2016 / 2019 / 2021 / Office 365 | mso 16 |
<!--[if gte mso 16]> |
The Architecture of Ghost Tables
Modern responsive emails often use <div> tags with max-width: 600px and display: inline-block to create responsive multi-column layouts without media queries.
However, Microsoft Word completely ignores max-width on <div> elements, expanding them to fill 100% of the screen (blowing out your layout across widescreen monitors).
The Solution: Ghost Tables. We wrap our fluid container in conditional table tags that exist only in Outlook's DOM:
<!-- Outlook sees: <table width="600"><tr><td> -->
<!--[if (gte mso 9)|(IE)]>
<table role="presentation" width="600" align="center" cellpadding="0" cellspacing="0" border="0">
<tr>
<td>
<![endif]-->
<div style="max-width: 600px; margin: 0 auto;">
<!-- Fluid content for WebKit/Blink -->
</div>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
To Apple Mail, Gmail, and mobile browsers, the <!--[if mso]> comments are standard HTML comments, so they render a fluid <div>. To Outlook, the <div> is safely constrained inside a rigid 600px <td>.
Vector Markup Language (VML)
Microsoft Word cannot render CSS background-image, background-size: cover, or CSS border-radius. Instead, it includes an ancient XML-based vector graphics engine: VML (Vector Markup Language).
To use VML, declare the XML namespace on the <html> root:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office">
Bulletproof VML Hero Background Image:
<!--[if mso]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="width:600px;height:300px;">
<v:fill type="tile" src="https://example.com/hero.jpg" color="#1E293B" />
<v:textbox inset="0,0,0,0">
<![endif]-->
<div style="background-image: url('https://example.com/hero.jpg'); background-color: #1E293B; width: 100%; max-width: 600px; height: 300px;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td style="padding: 40px; color: #FFFFFF; text-align: center;">
<h1 style="margin: 0; font-size: 28px;">Hero Banner Content</h1>
</td>
</tr>
</table>
</div>
<!--[if mso]>
</v:textbox>
</v:rect>
<![endif]-->
Fixing the 120 DPI / 150% Windows Scaling Bug
On modern Windows laptops with 4K or high-resolution displays, Windows defaults display scaling to 125% (120 DPI) or 150% (144 DPI).
When Microsoft Word encounters an email on a 120 DPI display, it multiplies all pixel values by 1.25x:
- A
600pxtable becomes750px. - Two
300pxcolumns become375pxeach, exceeding the table width and forcing the second column to wrap awkwardly underneath. - Text sizes inflate, but table cell widths may clip.
The Universal DPI Fix:
Place this XML definition inside your <head> within an MSO conditional comment:
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
Setting PixelsPerInch to 96 instructs Word to calculate all dimensions against standard 96 DPI baseline coordinates regardless of Windows OS zoom settings.
💻 Interactive Code Playground
Starter Code
Below is a complete, production-ready template utilizing MSO Ghost Tables and High-DPI XML settings.
Line-by-Line Code Breakdown
- Lines 2–4 (
xmlns:v="..." xmlns:o="..."): Declares the VML (v) and Office (o) XML schemas, enabling the browser or email parser to recognize VML vector primitives and document configuration nodes. - Lines 8–17 (
<!--[if mso]><noscript><xml>...): The 96 DPI override. Wrapping the<xml>block inside<noscript>prevents certain webmail parsers (like Outlook.com web) from printing raw XML text directly into the page. - Lines 28–34 (
<!--[if (gte mso 9)|(IE)]><table width="600"...>): Ghost Table open tag. Outlook 2000 (mso 9) through Outlook 2021 reads this as a valid<table>declaration. Modern browsers ignore it as an HTML comment. - Line 36 (
<div class="fluid-wrapper" ...>): Modern container with CSSmax-width: 600px. Modern browsers respectmax-width, while Outlook ignores the div and is constrained by the parent ghost table. - Lines 49–54 (
<!--[if (gte mso 9)|(IE)]></td></tr></table><![endif]-->): Ghost Table closing tags, completing the DOM structure for Outlook.
Expected Browser Render Output
+-----------------------------------------------------------------------+
| [Canvas: #0F172A] |
| |
| +---------------------------------------------------+ |
| | Dual-Engine Hybrid Container | |
| | | |
| | Outlook is safely locked inside a rigid 600px | |
| | MSO Ghost Table, while modern mobile clients | |
| | render a fluid responsive box model. | |
| +---------------------------------------------------+ |
| |
+-----------------------------------------------------------------------+🏋️ Hands-On Exercise
🎯 The Challenge: Build a 2-Column Ghost Table Grid
Instructions:
- Configure an HTML email root with VML namespaces and the 96 DPI MSO override block.
- Build an outer canvas table with dark background
#0F172A. - Construct a 2-column layout where modern browsers receive two
display: inline-block; width: 280px;divs that stack automatically on mobile screens. - Wrap the columns in an MSO Ghost Table so that Outlook Windows splits them into
<td width="280">and<td width="280">side-by-side without stacking.
🏁 Starter Code Sandbox
⚠️ Common Pitfalls
- Unclosed MSO Tags: Forgetting to close an
<!--[if mso]>block or misplacing the closing</td></tr></table>will cause the entire rest of your email to vanish in Outlook. - Forgetting
<noscript>Around Office XML: In webmail versions of Outlook, raw<xml>blocks outside of<noscript>can occasionally be rendered on-screen as garbled plaintext code. - Relying on CSS
background-imagein Outlook: Outlook for Windows simply ignoresbackground-imagedeclarations. If you need a background image in Outlook, you MUST provide a VML<v:rect>fallback.
💡 Pro Tips
- Use Downlevel-Revealed Comments for Mobile-Only Features: To completely hide mobile hamburgers or app banners from Outlook, use
<!--[if !mso]><!--> ... <!--<![endif]-->. Outlook will skip parsing it entirely. - Explicit Width Attributes on Ghost TDs: Always specify both HTML attribute
width="280"and CSS stylestyle="width: 280px;"on ghost table cells to prevent high-DPI scaling overrides. - Set Parent
font-size: 0pxon Inline-Block Containers: When usingdisplay: inline-blockon adjacent divs, HTML whitespace between tags creates an invisible 4px gap. Settingfont-size: 0pxon the parent container eliminates this gap across WebKit and Blink.
📌 Key Takeaways
- MSO Conditional Comments (
<!--[if mso]>) allow engineers to target Microsoft Word/Outlook specifically without affecting modern clients. - Ghost Tables wrap fluid
<div>elements inside conditional<table>tags, delivering responsive fluid behavior to modern clients and rigid table geometry to Outlook. - VML (Vector Markup Language) is required to render background images and vector shapes in Windows Outlook.
- The 120 DPI Windows scaling bug is solved by injecting
<o:OfficeDocumentSettings><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings>in<head>. - Downlevel-revealed syntax (
<!--[if !mso]><!-->) hides modern, interactive, or mobile-specific markup from Outlook. - --