Last Updated:

Using MSO- styles in Email

If you’ve been working in email dev, you may have come across mso- prefixed styles in the code, I mention them a few time on this site. MSO styles are styles that are specific to MSO (MicroSoft Office), some of these styles are unique to MSO but often these are repeats of standard CSS styles, in which case they can be used to provide a different value in MSO email clients.

The MSO email clients include Outlook desktop app on Windows, and Windows Mail the rendering of these apps is based on Microsoft Word. Other versions of Outlook, such as the Mac app, Android app, iOS app, the webmail and Progressive Web Apps (PWA) use regular HTML rendering and don’t support these MSO styles.

There are a lot of MSO prefixed styles as documented in this great resource, Stig’s MSO reference page. Stig got this recourse from Jason who shared a Microsoft Office HTML and XML Reference PDF that he in turn downloaded and decoded from this Microsoft® Office HTML and XML Reference. This is one of the things I love about the email community, people are happy to share their findings and expand on each other’s work.

Over the years, I’ve gone through this document and a few others and made some notes about which of these style work in Outlook and how to use them.

There is quite a lot to cover, so I’ve broken it down into a few sections to hopefully make things easier to follow

MSO text styling

There are a few different font types used here ascii, ansi, bidi, fareast, hansi, symbol. Depending on what language you’re sending in ,you may need to adjust some of these styles accordingly (I need to do more testing around this). For now I’m focusing on English content, so looking at ascii and ansi.

mso-ansi-font-size

Works in a similar way to font-size. Additionally, it will accept a unitless font (mso-ansi-font-size:30) and treat is as 30px

<p style="mso-ansi-font-size:30px">test</p>

mso-ansi-font-style

Works just like font-style

<p style="mso-ansi-font-style:italic">test</p>

mso-ansi-font-weight

Works just like font-weight

<p style="mso-ansi-font-weight:bold">test</p>

mso-ansi-language

This can be used to define a language, Outlook will pass this value onto a lang="" attribute.

<p style="mso-ansi-language: es">prueba</p>

mso-ascii-font-family

Works just like font-family

<p style="mso-ascii-font-family:Arial, sans-serif">test</p>

mso-generic-font-family & mso-font-alt

These don’t appear to work in the majority of places however, they can be used as part of a fallback for webfonts, Read more about web font fallback with mso-generic-font-family on hteumeuleu.com

mso-font-width

This works a bit like transform:scaleX() but is only applied to the text and unlike transform this does affect the flow of the DOM.

It is set as a % where 100% is the default value.

<p style="mso-font-width:50%">test</p>

mso-color-alt / mso-style-textfill-fill-color

Both work just like color

<p style="mso-color-alt:#ff0000">test</p>
<p style="mso-style-textfill-fill-color:#ff0000">test</p>

mso-line-height-alt

Works just like line-height. When using unitless values they need to be whole numbers and not decimals. If you want a line height of1.5 you can use 150% or 1.5em.

<p style="mso-line-height-alt:150%">test</p>

mso-line-height-rule

This is a modifier for line-heightto say if the rule should be applied exactlyor at-least. It’s only applies to fixed unit values like px and uses at-leastas the default value.

When using relative units like % this is not needed and line-height will work as expected.

It’s only needed if you have a very small line height, set with a fixed unit.

<p style="mso-line-height-alt:10px; mso-line-height-rule:exactly;">test</p>

mso-style-textfill-fill-alpha

Works like opacity but only works on text and only accepts % values.

<p style="mso-style-textfill-fill-alpha:50%;">test</p>

mso-style-textfill-type: none

Similar to color:transparent MSO email clients don’t respect the transparent keyword so this can be used as a work around for that.

<p style="mso-style-textfill-type: none">test</p>

Also see mso-style-textfill-type: gradient

mso-text-indent-alt

Works just like text-indent

<p style="mso-text-indent-alt:50px">test</p>

mso-text-raise

Similar to padding-bottom but also works on inline elements. It can also take a negative value to make it similar to padding-top

<p style="mso-text-raise:50px">test</p>
<p style="mso-text-raise:-50px">test</p>

text-underline-color

Works just like text-decoration-color

<p style="text-decoration:underline; text-underline-color: #FF0000">test</p>

mso-char-indent

Works in a similar way to text-indent. This is the shorthand version of mso-char-indent-count (how many characters to indent by) and mso-char-indent-size(how big those characters are). However the indent size dosn’t work in Outlook so we can only set the count, but this works either as long hand or short hand.

<p style="mso-char-indent: 2">test</p>
<p style="mso-char-indent-count: 2">test</p>

For a closer comparison to text-indent see mso-text-indent-alt

MSO advanced text styles (Word Art)

Back in the 90’s if you want to create a poster for your school disco, you would do it in MS Word using Word Art. If you’re still loving this retro style then we can recreate it in Outlook too.

mso-effects-shadow

Ok this is a complicated one, it’s similar to text-shadow but works a little differently.

<p style="mso-effects-shadow-color: #ff0000; mso-effects-shadow-alpha: 100%; mso-effects-shadow-dpiradius: 0pt; mso-effects-shadow-dpidistance: 10pt; mso-effects-shadow-angledirection: 5400000; mso-effects-shadow-pctsx: 100%; mso-effects-shadow-pctsy: 100%;">
  test
</p>

So I’ll break that down

mso-style-textoutline

This is similar to CSS -webkit-text-stroke which is an experimental feature that’s been sitting in the experimental box for some time. Chris Coyier has a good article on CSS text-stroke

<p style="font-size:50px; mso-style-textoutline-type:solid; mso-style-textoutline-fill-color:red; mso-style-textoutline-outlinestyle-dpiwidth:1pt;">test</p>

I’ll break this down as well

Those first 3 are required, but if you want some more options…

mso-style-textfill-type: gradient;

<p style="mso-style-textfill-type: gradient;
mso-style-textfill-fill-gradientfill-shadetype:linear;
mso-style-textfill-fill-gradientfill-shade-linearshade-angle:
0;mso-style-textfill-fill-gradientfill-stoplist:'0 \#000000 1 100000\,50000 \#C00000 -1 100000\,100000 \#000000 1 100000'">
test
</p>

MSO Box Model

mso-margin-top-alt, mso-margin-bottom-alt

Works just like margin-top and margin-bottom. But doesn’t work with left, right or shorthand values.

<p style="mso-margin-top-alt:1em;mso-margin-bottom-alt:1em;">test</p>

mso-padding-alt

Works just like padding. Also supports longhand values mso-padding-top-alt, mso-padding-right-alt, mso-padding-bottom-alt, mso-padding-left-alt

<p style="mso-padding-top-alt:1em;mso-padding-bottom-alt:1em;background:red;border:1px solid;">test</p>

For padding to work on a <p> we also need to add a border.

mso-padding-between

This only works when mso-border-between is set on a element. It sets the padding the 2 elements that Outlook has joined

<p style="border:4px solid green;mso-border-between:4px dotted pink; mso-padding-between:50px">test</p>
<p style="border:4px solid green;">test</p>

mso-border-alt

Works just like border. Also supports longhand values for sides mso-border-top-alt, mso-border-right-alt, mso-border-bottom-alt, mso-border-left-alt and for settings mso-border-style-alt, mso-border-color-alt, mso-border-width-alt

<p style="mso-border-alt:4px solid green">test</p>

mso-border-between

Outlook will sometimes combine block level elements that are adjacent to eachother, which have matching border styles. For example if you have 2 <p> elements both with a border, you may only see an outer border around both elements and not between them. To fix this we can set a border between them, this could also be set as a different value.

<p style="border:4px solid green; mso-border-between:4px dotted pink;">test</p>
<p style="border:4px solid green;">test</p>

This can be combined with mso-padding-between

This could also be useful on tables

<table style="border:1px solid green;mso-border-between:1px dashed red; mso-padding-between:50px">
	<tr>
		<td>test1</td><td>test2</td>
	</tr>
	<tr>
		<td>test3</td><td>test4</td>
	</tr>
</table>

mso-border-shadow

Similar to box-shadow but with less control. This only works when a border is set, and the options are just yes and no, if yes then a black shadow will be added to the bottom right at the same width as the border.

<p style="border:solid red 8px; mso-border-shadow:yes">test</p>

MSO Backgrounds

mso-shading

Works just like background-color

<p style="mso-shading: red">test</p>

mso-pattern

This adds a simple predefined pattern. This can also take the longhand form mso-pattern-color and mso-pattern-style

The style options include; diag-cross, diag-stripe, gray-025, gray-0625, gray-075, gray-10, gray-125, gray-15, gray-175, gray-20, gray-225, gray-25, gray-275, gray-30, gray-325, gray-35, gray-375, gray-40, gray-425, gray-45, gray-475, gray-5, gray-50, gray-525, gray-55, gray-575, gray-60, gray-625, gray-65, gray-675, gray-70, gray-725, gray-75, gray-775, gray-80, gray-825, gray-85, gray-875, gray-90, gray-925, gray-95, gray-975, horz-cross, horz-stripe, none, reverse-diag-stripe, solid, thick-diag-cross, thin-diag-cross, thin-diag-stripe, thin-horz-cross, thin-horz-stripe, thin-reverse-diag-stripe, thin-vert-stripe, vert-stripe

<p style="mso-pattern:vert-stripe red">test</p>
<p style="mso-pattern-color:red; mso-pattern-style: vert-stripe">test</p>

MSO table styles

mso-cellspacing

Works just like cellspacing="" attribute. This can be set with a unit, in which case it will be treated as px

<table style="mso-cellspacing:20px">
	<tr>
		<td>test</td>
	</tr>
</table>

mso-cell-special

I’m not too sure what this does but using mso-cell-special: placeholder will remove a <td> from the DOM.

mso-table-dir

Similar to the dir="" attribute, this sets the language direction of the table. Values are normal (left to right), rtl (right to left), bidi (bidirectional).

<table style="mso-table-dir:bidi">
	<tr>
		<td>a</td><td>b</td>
	</tr>
</table>

mso-table-tspace

These are similar to margin-top but only when the table is floated with an align="left" or align="right" attribute.

<table style="mso-table-tspace:50px;" align="left">
	<tr>
		<td>test</td>
	</tr>
</table>

mso-table-lspace

These are similar to margin-left but only when the table is floated with an align="left" or align="right" attribute.

<table style="mso-table-lspace:50px;" align="left">
	<tr>
		<td>test</td>
	</tr>
</table>

mso-table-rspace

These are similar to margin-right but only when the table is floated with an align="left" or align="right" attribute.

<table style="mso-table-rspace:50px;" align="left">
	<tr>
		<td>test</td>
	</tr>
</table>

mso-table-bspace

These are similar to margin-bottom but only when the table is floated with an align="left" or align="right" attribute.

<table style="mso-table-bspace:50px;" align="left">
	<tr>
		<td>test</td>
	</tr>
</table>

MSO List styles

mso-special-format

When adding a left margin to lists <ul> or <ol>, Outlook likes to convert the <li> elements into <p> elements and will mess with the spacing. This is flipped in rtl languages to the right margin.

We can work around this by adding mso-special-format:bullet;

<ul style="margin-left:10px;" >
	<li style="mso-special-format:bullet;">Test</li>
	<li style="mso-special-format:bullet;">Test</li>
	<li style="mso-special-format:bullet;">Test</li>
</ul>

However this will also reset to the default margin (about 48px in Outlook) and default list-style-type: disc;

mso-bullet-image

Works similar to list-style-imagebut only accepts gif and ico formats. Also it requires setting mso-special-format:bullet

<ul>
  <li style="mso-special-format:bullet;mso-bullet-image:'https://dummyimage.com/600x400/fff/000.gif&text=✓'">
    test
  </li>
</ul>

If you want to remove a list icon to replicate, list-style: none you could use a transparent gif as the mso-bullet-image.

MSO element

When using mso-elements you’ll see a border appear around the first element used. I’ve not worked out how to remove this yet but we can set another element first that will take the boarder then move that out of the way.

Place this code at the top of your email

<div style="mso-element-wrap:none;mso-element-left:right;font-size:1px;">&zwnj;</div>

You will still see it in the top right corner but this is the best I have so far.

mso-element

This is used to set an element. In it doesn’t do much on it’s own. However be aware that setting a valuse of none will remove all the content after it.

<div style="mso-element:none"></div>

So don’t do that.

mso-element-frame-width

Set the width of the mso-element. There is no need to a set mso-element: frame, In Outlook the rendered code becomes a <table>

<div style="mso-element-frame-width:600px;">test</div>

mso-element-frame-height

Set the height of the mso-element. There is no need to a set mso-element: frame, In Outlook the rendered code becomes a <table>

<div style="mso-element-frame-height:400px;">test</div>

mso-element-wrap

This sets the wrapping of the mso-element, it works a bit like CSS float

Here’s an example of it used for a drop-cap on a paragraph.

<div style="font-size:48px; mso-element-wrap:around;">L</div>
<p>orem ipsum dolor sit amet, consectetur adipiscing elit.<br> 
Aenean tincidunt, diam a rutrum tristique, tellus turpis malesuada enim, sed luctus est turpis quis sem.<br>
Ut tellus augue, pulvinar ac nunc iaculis, interdum tristique orci.<br>
Curabitur maximus lacus erat, vitae rutrum tortor ullamcorper in.</p>

mso-element-left

Positioning from the left, similar to margin-left

There is also mso-element-top but I’ve not get ot working yet

mso-element-frame-vspace

Works like css margin-block to give vertical space. This requires setting a mso-element-frame-height, mso-element-frame-width or mso-element-wrapto make the vspace work.

<div style="mso-element-wrap:no-wrap-beside;mso-element-frame-vspace:20px;">test</div>

mso-element-frame-hspace

Works like css margin-inline to give horazontal space. This requires setting a mso-element-frame-height, mso-element-frame-width or mso-element-wrapto make the hspace work.

<div style="mso-element-wrap:no-wrap-beside;mso-element-frame-hspace:20px;">test</div>

More to come

I’ve had this half finished for a few months and very slowly adding to it, but I’ve already referenced it a few times so I decided I’ll put it live and finish it off when I get time.