Outlook.com’s latest bug and how to fix gaps under images

Last month, Microsoft introduced a new feature in Outlook.com and Office 365 that caused a lot of headaches to email developers. This has been discussed widely by the community, may it be on Slack or on Litmus forums. But it has been obsessing me over the past two weeks. Here’s everything you need to know about this bug and my quest to find a fix.

The feature

If an image doesn’t have any link, Outlook.com makes it clickable to show an image preview overlay. From this overlay, you can slide through all other images from this email.

Clicking on an image without a link (no pun intended) opens a preview overlay in Outlook.com.

I’m sure this is a nice feature if you were to receive an email with family photos. And this kind of feature is not really new in the webmail world. It’s akin to Yahoo Rich Link Previews or Gmail’s download image icons.

Unfortunately, Microsoft’s implementation of this feature is about as bad as it could have gotten.

The bugs

The most visible bug due to this feature is that every image now gets a small gap below it.

See the code for this example.

In order to get this to work, Outlook.com adds its own HTML tags around every images. Take the following code for an image.

<img alt="" src="botw.jpg" alt="" style="display:block; max-width:100%;" />

Here’s that code after Outlook.com transforms it.

<div style="display: inline-block; max-width: 99.9%;">
<button type="button" class="_at_6 o365button" aria-labelledby="_ariaId_107">
<img alt="" src="botw.jpg" alt="" style="display:block; max-width:100%" />
<span class="_fc_3 owaimg" style="display: none;"></span>
<span class="_fc_4 o365buttonLabel" id="_ariaId_107" style="display: none;"></span>
</button>
</div>

Let’s break down what’s going on with that code:

  1. It adds an outer <div> set as display:inline-block in CSS, even though my image initially had a display:block. This is what’s causing gaps to appear (similar to what’s happening to an <img> within an HTML5 page).
  2. This parent <div> has a max-width:99.9% applied. This only happens if the image has a max-width:100% (which is pretty frequent in responsive emails). Depending on the way you slice your images, or if you have any background color, this can create visible horizontal offsets.
  3. It adds a <button> tag around the image (with two <span>s inside as well). Note that this only happens if the image has no link around it.

Various solutions have been suggested to minimize the downsides of these code additions by Outlook.com, like adding a font-size:0; to a parent element or wrapping every image with a class and then reset the styles of the elements added by Outlook.com. But that still didn’t solve the max-width:99.9% problem. And I hate the idea that Outlook.com adds random HTML right within my emails.

So from now on, I had a clear goal: find a way to prevent this.

And so my journey began.

The investigation

My first intuition was that there had to be some way to disable this behavior. So first, I tested different nestings of code to try to understand when this functionality was triggered. But it seems like no matter what I tried (like already wrapping the image with a <div> or a <button>), Outlook.com still added its own code.

One thing I noticed, though, is that the max-width:99.9% was only added when there was a max-width:100% on the image. But any other value of max-width (like 99%, 100.0001% or any value in pixels) would be safe.

Another more amusing thing I noticed was that while Outlook.com removed a lot of modern attributes on <img> tags (like srcset or sizes), it kept the ancestral dynsrc attribute. If you weren’t on the Web in the early 2000s, the dynsrc attribute was a proprietary attribute create by Microsoft to embed videos in web pages.

At this point I thought it would be funny to go on a little side quest and see if I could get a video to play in Outlook.com on an old Internet Explorer. So I launched one of my virtual machines (provided by Microsoft). If you’ve ever wondered what Outlook.com looks like on Internet Explorer 8, there you go.

On IE8, only minimal styling and not a single image shows up on Outlook.com.

That’s when I realized I’m an idiot because dynsrc is only supposed to work from Internet Explorer 4 to 6. Not having these browsers at hand, I stopped my side quest there.

But something caught my attention. In IE8, it appeared that none of the code related to the image preview was added. No <div>, no <button> and no max-width:99.9%. But the rest of the usual styles prefixing and filtering was still done by Outlook.com (like adding x_ before every class name or removing media queries).

I thought that was very interesting and from now on my hypothesis was that maybe all of this feature was added in JavaScript (and not server side). That would be really great, because if it’s done in JavaScript, I could find and read the actual related source code.

But because the whole webmail runs with JavaScript, I could not simply turn JavaScript off in my browser to see what was going on. So I used Chrome’s Timeline tool to try to see what was going on. Here’s a video of it in action.

https://www.youtube.com/watch?v=fdvow1PNgow

Moving on the timeline, I could definitely see the moment the lines appeared below every image. So my hypothesis was correct, and all of this is done in JavaScript. Following Chrome’s Timeline tool stack trace, I could see that the JavaScript functions executed at that moment came from a file named boot.worldwide.o.mouse.init.js.

Scrolling through that 25000 lines long file, I was able to find the exact same classes (_fc_3 and_fc_4) added around images by the webmail.

But somehow, I couldn’t get to trigger a breakpoint on this function. And the whole code being uglified, I couldn’t make sense of it at a greater scale.

So instead I decided to look for the origin of the max-width:99.9%. My intuition was that this was surely the result of a calculation with a rounding mistake done in JavaScript. So I went to search for maxWidth across all JavaScript sources. This resulted in nine matching lines.

It’s inside a file named microsoft.owa.core.attachments.js that I found what I was looking for.

v: function() {
this.a && (this.a.style.maxWidth === "100%" || this.a.style.maxWidth === "99.9%") && (this.z.style.maxWidth = "99.9%")
}

This very line of code says that if an element a exists, and if that element a has a max-width of 100% or 99.9%, then another element z gets a max-width:99.9% applied. That’s it. That’s exactly the behavior that I initially observed.

From then, I had a line to hook on. So I set a breakpoint, and jumped function after function calls to see if I could find anything interesting. And that’s when (after what felt like hours but was more likely a few minutes) I found it. The holy grail. In a file named microsoft.owa.attachments.extendedattachmentwell.js.

if(!t.id.startsWith("OWATemporaryImageDivContainer") && t.parentNode) { … }

That line says that if an element t doesn’t have an id attribute that starts with OWATemporaryImageDivContainer and has a parent element, then the rest of the code is executed. Which means that if an element has an id that starts with OWATemporaryImageDivContainer, then the rest of the code would be ignored.

So I tested that with my initial example.

<img alt="" src="botw.jpg" alt="" style="display:block; max-width:100%;" id="OWATemporaryImageDivContainer1" />

And it works. This code is left intact by Outlook.com. No extra HTML is added.

And thus my quest was over.

The fix

Add an id attribute that starts with OWATemporaryImageDivContainer to every <img> tag. Since every id should be unique, make sure to increment the value for each image or have a proper naming convention.

Now you can have a link on your images without anything breaking.

See the code for this example.

Afterwords

I spent more than ten hours investigating all of this. That’s more time it took me to create a funny forwardable email experiment. That’s almost two days of unpaid work to get around Microsoft lazy practices.

Ten years after choosing Word as a rendering engine for Outlook 2007, and almost a year after a supposedly historical partnership with Litmus, Microsoft is still consistently making life harder for the entire email industry. While other email client vendors (like Yahoo, Gmail or Apple Mail) have made huge improvements over the past few years, Microsoft keeps making every versions of Outlook worse and worse. (Have you heard about the lasted Outlook app on iOS and Android?) I’m at a point where I’m hesitant to publish such articles because I’m afraid Microsoft will try to update this and make things even worse.