Pieter van der Westhuizen

Working with Outlook HTMLBody – a guide for Office developers

If you’ve ever tried to design an attractive and somewhat complex e-mail message using Microsoft Outlook and HTML, chances are you very quickly realized that the Outlook mail message body format performs rather differently than a normal web browser.

Outlook HTMLBody is not a web page

The primary reason that your carefully designed Outlook HTML e-mail templates might not always look exactly the same in an e-mail body as it does inside your browser, is because since Outlook 2007, the Microsoft Word 2007 rendering engine has been used to parse and render HTML inside Outlook e-mail messages.

In previous versions of Outlook, Microsoft employed two rendering engines. For displaying / reading e-mail content, they employed the Internet Explorer rendering engine and used MS Word’s rendering engine for composing messages. Word 2007 made significant advancements in the way it handled HTML and CSS and the Outlook team decided to combine both reading and composing of Outlook e-mail messages with one technology.

In essence, the Word 2007 supports a subset of the HTML 4 specifications as well as a subset of the CSS specifications level 1. What this means is that not all HTML elements are supported inside an Outlook e-mail body.

Outlook HTML and CSS limitations

There is a rather wide range of limitations imposed on Outlook email HTML due to the fact that the MS Word rendering engine is being used. Some of the more obvious features that are not supported are:

  • Background images;
  • Animated GIF images;
  • HTML Forms; and
  • CSS Positioning and floats.

Inline styles

As a general rule of thumb, using inline styles are preferred over specifying your CSS inside a <style> tag. You should avoid linking to external style sheets altogether as it will not work at all. For example, in order to set a table’s border style, use the following syntax:

<table style="width: 100%;border-style: solid;border-width: 3px;">

Use Tables

Although the general consensus with regards to using HTML tables for web page layout is to rather avoid them, this is not the case with Outlook e-mail design. <div> elements inside Outlook e-mails tend to have a mind of their own and behave erratically. HTML Tables will give you a predictable layout experience and will work in almost all e-mail clients.

Text does not wrap

Speaking of Tables, text does not automatically wrap inside a table, which can cause some confusing results. To avoid this, style your table cell (<td>) elements as follows:

<td style="word-break:break-all"></td>

Unsupported HTML tags

The following table lists the HTML tags that are not supported in Outlook e-mails / Word rendering engine:

  • applet
  • bdo
  • button
  • form
  • iframe
  • input
  • isindex
  • menu
  • noframes
  • noscript
  • object
  • optgroup
  • option
  • param
  • q
  • script
  • select
  • accept-charset
  • accept
  • accesskey
  • archive
  • background (only when there is a URL)
  • checked
  • classid
  • code
  • codecore
  • codetype
  • compact
  • data
  • declare
  • defer
  • disabled
  • enctype
  • longdesc
  • marginheight
  • marginwidth
  • media ( screen | print | projection | braille | speech | all )
  • method
  • multiple
  • noresize
  • object
  • onblur
  • onchange
  • onclick
  • ondblclick
  • onfocus
  • onkeydown
  • onkeypress
  • onkeyup
  • onload
  • onmousedown
  • onmousemove
  • onmouseout
  • onmouseover
  • onmouseup
  • onreset
  • onselect
  • onsubmit
  • onunload
  • readonly
  • scrolling
  • selected
  • standby
  • tabindex
  • title
  • valuetype

Supported CSS

Below is a list of CSS properties that are supported inside an Outlook e-mail body:

  • color
  • font
  • font-family
  • font-style
  • font-variant
  • font-size
  • font-weight
  • text-decoration
  • background (only color)
  • background-color
  • text-align
  • vertical-align
  • letter-spacing
  • line-height
  • white-space
  • display
  • border
  • border-color
  • border-style
  • border-width
  • src
  • size
  • marks
  • page-break-before
  • page-break-after
  • page-break-inside
  • list-style
  • list-style-type
  • unicode-bidi
  • border-collapse
  • text-indent
  • margin
  • margin-left
  • margin-right
  • margin-top
  • margin-bottom
  • width
  • height
  • padding
  • padding-left
  • padding-right
  • padding-top
  • padding-bottom
  • border-left
  • border-right
  • border-top
  • border-bottom
  • border-left-color
  • border-left-width
  • border-left-style
  • border-right-color
  • border-right-width
  • border-right-style
  • border-top-color
  • border-top-width
  • border-top-style
  • border-bottom-color
  • border-bottom-width
  • border-bottom-style

A good list on what CSS properties are supported can be found on campaignmonitor.com.

HTML templates by Zurb

You might know Zurb from a previous article on this blog where we discussed their Foundation Framework for creating ASP.Net MVC websites. Their Foundation Framework can assist you with building responsive emails that will work on any device even Outlook as stated on the front page of their website.

The Ink framework provides a grid layout structure to help build the e-mail layout as well as easy ways to add padding to text, centre element and much more. Of course, one of the best features are their ready-to-use templates. They provide four templates that you can download and use immediately in order to build your HTML emails in Outlook.

These templates contain all the necessary HTML and CSS to make your email content look good inside Outlook. For example, in the following image, I’ve simply inserted the HTML from the Ink Sidebar template, and everything displays great inside Outlook:

Ink Sidebar HTML template for Outlook

Embedding images in an Outlook E-mail

When it comes to embedding images into your Outlook e-mails, you have a choice to either embed you images directly into the e-mail or reference the image from an internet URL.

The problem with referencing an URL for the image is that Outlook would probably block the image and display the “To help protect your privacy, Outlook prevented automatic downloads of some pictures in this message” message.

Outlook prevented automatic downloads of some pictures in this message

This is done for a very specific reason, because the image URL could contain more information than simply the URL to the image. It could also contain information that could inform the sender when you read the message – this is a technique that can also be exploited by spammer in order to determine whether the e-mail addresses used does exist.

The safer route is to embed your images in the e-mail when creating them. This does take some doing, but the end result is a good formatted email, which makes it worth the effort.

To illustrate, I’ve included the following code. By setting three properties, we’ll embed an image of the Add-in Express logo into the Outlook e-mail once the user clicks a button on the Mail Inspector window. This is done by first adding the image as an attachment to the email and then setting the <img> tags’ source property to the unique id.

private void adxRibbonButtonEmbedImage_OnClick(object sender,
    IRibbonControl control, bool pressed)
{
    Outlook.Inspector currInspector = null;
    Outlook.MailItem currMail = null;
    Outlook.Attachments attachments = null;
    Outlook.Attachment image = null;
    Outlook.PropertyAccessor propertyAccessor = null;
 
    try
    {
        currInspector = OutlookApp.ActiveInspector();
        if (currInspector.CurrentItem is Outlook.MailItem)
        {
            currMail = currInspector.CurrentItem as Outlook.MailItem;
            attachments = currMail.Attachments;
            image = attachments.Add(@"C:\temp\Add-in_Express_Logo.jpg");
            propertyAccessor = image.PropertyAccessor;
            propertyAccessor.SetProperty(
                "http://schemas.microsoft.com/mapi/proptag/0x370E001F", "image/jpeg");
            propertyAccessor.SetProperty(
                "http://schemas.microsoft.com/mapi/proptag/0x3712001F", "myImageId");
            propertyAccessor.SetProperty(
                "http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B", true);
 
            string htmlBody =
                "<html><head><title></title></head><body><img src=\"cid:myImageId\"/></body></html>";
            currMail.HTMLBody = htmlBody;
        }
    }
    finally
    {
        if (attachments != null) Marshal.ReleaseComObject(attachments);
        if (image != null) Marshal.ReleaseComObject(image);
        if (propertyAccessor != null) Marshal.ReleaseComObject(propertyAccessor);
        if (currMail != null) Marshal.ReleaseComObject(currMail);
        if (currInspector != null) Marshal.ReleaseComObject(currInspector);
    }
}

The resulting Outlook e-mail will have the image embedded inside its HTML body as illustrated below:

An image embedded inside the HTML body of an Outlook email

Thank you for reading. Until next time, keep coding!

Available downloads:

This sample Excel add-in was developed using Add-in Express for Office and .net:

Outlook HTMLBody sample add-in

16 Comments

  • https://secure.gravatar.com/avatar/cb2002c20be621a1c6723e3197e19481?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Ferhat Ergin Turan says:

    Here is my Screen view, i can put it inside the outlook mail new item (it is OK)
    But i have photo and text problem :( i want to write text on photo :(

    http://s9.postimg.org/turyh5o27/mainn.jpg

    Here is codes…

    procedure TForm1.Button1Click(Sender: TObject);
    var
    i: integer;
    Outlook: OleVariant;
    Mail: OleVariant;
    const
    olMailItem = 0;
    olByValue = 1;
    olFormatHTML = 2;
    begin
    i:=0;
    for i:= 0 to listbox1.Count-1 do
    begin
    try
    Outlook := GetActiveOleObject(‘Outlook.Application’);
    except
    Outlook := CreateOleObject(‘Outlook.Application’);
    end;
    Mail := Outlook.CreateItem(olMailItem);
    Mail.To:=ListBox5.Items[i];
    mail.cc :=’kabinyolsefmg at thy dot com; ‘;
    Mail.Subject :=COMBOBOX1.Text;

    Mail.Attachments.Add(‘c:\tts\mainn.png’, olByValue, 1, ‘My Test Image’);
    Mail.BodyFormat := olFormatHTML;
    Mail.HTMLBody:= ”+
    ‘.font {font-family: Calibri;}.font {font-size: 14px;}’+
    ”+
    ”+
    ”+

    ‘+
    ‘Hello’+
    ‘This is my email text’+
    ‘i cant put it inside the box’+
    ”+
    ”;

    Mail.Display;
    end;
    end;

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Ferhat,

    You can create such an email manually, then extract the HTML using the context menu item ViewSource, study the HTML and create the same in the code of your add-in.

  • https://secure.gravatar.com/avatar/41b420093353e172aa814abaf381f540?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Starhunter says:

    Hello.

    Is this tested Outlook 2016?

    I can’t get the htmlbody property in Outlook 2016 HtmlFormat MailItem.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello,

    Make sure MailItem.BodyFormat returns olFormatHTML. If “can’t get” means the call produces an exception, please provide details.

  • https://secure.gravatar.com/avatar/9413ca8f4ac801599149c3854b5c1008?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G mrblint says:

    In Outlook 2016, I can’t access the HTMLBody property either. I get this error in the debugger when I try to examine the variable in the Immediate Window:

    ?mailItem.HTMLBody
    error CS1061: ‘MailItem’ does not contain a definition for ‘HTMLBody’ and no extension method ‘HTMLBody’ accepting a first argument of type ‘MailItem’ could be found (are you missing a using directive or an assembly reference?)

    but

    ?mailItem.Subject

    works fine.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello,

    Make sure that you set an Outlook.MailItem to the mailItem variable. For instance, you can check mailItem.Class; if mailItem contains an Outlook.MailItem, mailItem.Class will return olMail (=43). I would declare the variable as Outlook.MailItem to avoid such issues.

  • https://secure.gravatar.com/avatar/029672d128573d38e008b78d2a334601?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Allen says:

    In Outlook 2016, I can’t access the HTMLBody property either too.
    Is this issue closed? if so, please help me..
    My outlook can’t access HTMLBody, and Body properties.
    And I also declare like ‘Outlook._MailItem mail = (Outlook._MailItem)ItemObj;’

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Allen,

    What do you mean by “can’t access”? Are you getting an exception? What’s the error message?

  • https://secure.gravatar.com/avatar/a0c5988b0b2904e1d6916a4b30c44d94?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G MissBow says:

    Hello I’m trying to open an .oft file (this works) and take the location and body of the template and place these into a new outlook appointment which I’ve also just created. So far everything works except I can’t figure out how to get the body of the template into the new outlook appointment. Code below. The code is run when a button in excel is clicked.

    Sub CreateInvite()
    Dim otlApp As Object
    Dim otlNewMail As Object
    Dim objItem As Object
    Dim location As String
    Dim meetingTemplate As String
    Dim i As Integer
    Dim EmailTo As String

    ‘ Create the Outlook session
    Set myoutlook = CreateObject(“Outlook.Application”)
    ‘ Create the AppointmentItem
    Set myapt = myoutlook.CreateItem(olAppointmentItem) ‘ Set the appointment properties

    i = 10
    meetingTemplate = “C:\..\..\..\myfile.oft”

    ‘ Create the Outlook session
    Set otlApp = CreateObject(“Outlook.Application”)
    ‘ Create the AppointmentItem from template
    Set otlNewMail = otlApp.CreateItemFromTemplate(meetingTemplate)

    With myapt
    .Actions(“Forward”).Enabled = False
    .Actions(“Reply to All”).Enabled = False
    .Subject = “Tamayoz ExxonMobil Qatar Training: ” & Cells(1, 2).Value & ” on ”
    .location = otlNewMail.location
    .Start = Cells(1, 6).Value & ” 08:00:00 AM”
    .End = Cells(1, 8).Value & ” 17:00:00 PM”
    .MeetingStatus = olMeeting
    Do While Cells(i, “J”).Value “” Or i <= 39 'continue through loop i is less than 21 and it doesn't hit an empty cell
    '.RequiredAttendees = Cells(i, "J").Value & ";"
    EmailTo = EmailTo + Cells(i, "J").Value & ";"
    i = i + 1
    Loop
    .RequiredAttendees = EmailTo
    .BusyStatus = "2"
    .ReminderSet = False
    .BodyFormat = olFormatHTML
    .HTMLBody = otlNewMail.HTMLBody
    .Display
    End With

    otlNewMail.Close 1
    Set otlNewMail = Nothing
    Set otlApp = Nothing

    End Sub

  • https://secure.gravatar.com/avatar/49725ba2a55928b7db7fe5927607ab26?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Manish says:

    Hi,

    I am creating a outlook addin to insert HTML template in mail body.
    Can anyone tell me how to insert my HTML template in mailitem.HTMLBody at cursor position without loosing any previous HTML formating?

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Manish,

    I would research this way. If pasting an HTML template to the email works correctly, I would check all the formats available in the clipboard at this moment. Then I would prepare all the formats relating to pasting the HTML template and “click” the Paste Ribbon button programmatically. To do this, you call Inspector.CommandBars.ExecuteMso(“Paste”). If you execute this code line in a compose inspector, it pastes the content of the clipboard to the email in the current cursor location.

    Another variant is this. You can get Inspector.WordEditor, cast it to Word.Document and then use the Word object model to find the cursor location (see Eord.Selection) and paste the template using the Range.PasteSpecial() method (see https://msdn.microsoft.com/en-us/library/office/ff821124(v=office.15).aspx) or Selection.PasteSpecial(). This also requires preparing the content of the Clipboard.

    HTH ))

  • https://secure.gravatar.com/avatar/49725ba2a55928b7db7fe5927607ab26?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Manish says:

    Hi Andrei,

    I am using this method to get the current cursor location and paste the template at cursor position. (see https://msdn.microsoft.com/en-us/library/6b9478cs(VS.80).aspx). and my requirement is that user should be able to insert multiple HTML templates in a single mail and also the new template should be inserted at the current cursor position. So every thing works fine till 1st template. but when user insert the second template all the html formation is lost for the 1st template. I am using below code

    SelectionInsertTemplate(subjetBody[1], document);
    mailItem.HTMLBody = document.Content.Text;
    mailItem.Subject = subjetBody[0];
    uniqueKey = subjetBody[2];
    mailItem.Save();

    Where subjetBody[1] contains HTML template.
    SelectionInsertTemplate is function which contains code mention at above link.
    Can you suggest any modification?

    Thanks in advance.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Manish,

    You shouldn’t modify HTMLBody. You should only modify the Word.Document object which you retrieve using Outlook.Inspector.WordEditor. The cursor location is Document.Windows(1).Selection.

    Inserting HTML is only supported by Word in two forms: 1) set the HTML to Clipboard and call Range.PasteSpecial (Selection.PasteSpecial) or 2) set the HTML to a file and call Range.InsertFile (Selection.InsertFile). These methods invokes the internal HTML converter. Alternatively, you can prepare an RTF text and insert it.

  • https://secure.gravatar.com/avatar/d7df464aa71980c88d222d7aac4ea9a1?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Rajesh Somvanshi says:

    Hi Pieter,

    This is a Very nice post.I have done my work by this post.

    Thank you so much.
    Rajesh Somvanshi

  • https://secure.gravatar.com/avatar/49725ba2a55928b7db7fe5927607ab26?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Manish says:

    Hi Andrei,

    Thanks Your suggestion works for me.

    Regards,
    Manish

Post a comment

Have any questions? Ask us right now!