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
- MSO advanced text styling (Word Art)
- MSO box model
- MSO backgrounds
- MSO table styles
- MSO List styles
- MSO element
- more 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-effects-shadow-colorset the colour.mso-effects-shadow-alphasets the opacity of the shadow.mso-effects-shadow-dpiradiussets the amount of blur on the .shadow.mso-effects-shadow-dpidistancesets the distance the shadow is away from the text.mso-effects-shadow-angledirectionThis sets the angle of the shadow. The units it uses are 1/60000th of a degree, with 0 being out to the right of the text. So if you want it directly below the text, that’s a 90° degree angle × 60000 = 5400000.mso-effects-shadow-pctsxsets the scale of the shadow on the X axis.mso-effects-shadow-pctsysets the scale of the shadow on the Y axis.
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
mso-style-textoutline-typesets our text outline assolidorgradient. I’m just focusing on solid for the moment.mso-style-textoutline-fill-colorsets the colour of the outline.mso-style-textoutline-outlinestyle-dpiwidthsets the thickness of the outline.
Those first 3 are required, but if you want some more options…
mso-style-textoutline-fill-alphasets the opacity of the outline.mso-style-textoutline-outlinestyle-dashsets the outline style a bit likeborder-stylethe options aresolid(default),dotsys,dashsys,dashgel,dashdotgel,longdashgel,longdashdotgel,longdashdotdotgelmso-style-textoutline-outlinestyle-compoundis also a bit likeborder-stylethese options aresimple(default),double,tripple,thickthin,thinthick. Also take a look back at mso-style-textfill-fill-alpha as that pairs well with using an outline.
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-style-textfill-type: gradient;set this as a gradient fill.mso-style-textfill-fill-gradientfill-shadetype: linear;sets the type of gradient fill, options arelinear(default) not sure about other options yet.mso-style-textfill-fill-gradientfill-shade-linearshade-angle: 5400000;sets the direction of the gradient. Again this uses units of 1/60000th of a degree, with 0 being a left to right gradient.mso-style-textfill-fill-gradientfill-stoplist:"0 \#000000 1 100000\,50000 \#C00000 -1 100000\,100000 \#FFFFFF 0 0sets the colours of the gradient as a comma separated list.- Each part has a position, set in 1/1000th of a % (so that means 50000 = 50%).
- Then a hex colour escaped with a
\. - Then a number representing something I don’t understand yet, but may is to do with blending over the underneath color.
-1seems to do what we need. - Then opacity set in 1/1000th of a %
- Additionally we can also add
lumm=90000 lumo=3000which I’m assuming stands for Luminance & Luminosity.
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-para-margin
Works just like margin also supports short hand values and longhand mso-para-margin-top, mso-para-margin-right, mso-para-margin-bottom, mso-para-margin-left.
<p style="mso-para-margin:0 0 3em 5em;">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. Inline elements like <span>, <a> only support a single style which will be applied to all sides. Block elements like <div>, <table> support different values on each side.
There is also support for 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. On inline elements these will be applied to all 4 sides.
<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 in a similar way to the cellspacing="" attribute or like the border-spacing style in CSS. Using mso-cellspacing mean we can use other units such as em to improve accessibility which isn’t possible using the cellspacing="" attribute. The value can also set with a unit, in which case it will be treated as px.
<table style="mso-cellspacing:1em">
<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;">‌</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
- around works like float, other elements will wrap around it
- auto Sets to around
- none works like position, absolute and takes the element out of the flow of the DOM
- no-wrap-beside similar to display:block puts the element on it’s own line
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
- center acts like
margin:0 auto;and centres the element. This only works whenmso-element-wrap:no-wrap-beside;is set. - [length] sets a value with units (
mso-element-left:50px). Acts likemargin-left. This only works whenmso-element-wrap:no-wrap-beside;is set. - left/right Acts like
float:leftfloat:right - inside/outside Appears to do the same as left/right
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.