Posted by Gavin Bannerman on April 15, 2020 | browsers

This blog post will expire on 9th January 2029. You may not recognise that date, but it’s a day that will be celebrated by many web developers across the world. It’s the date that Windows 10, and therefore Internet Explorer 11, will no longer be supported by Microsoft. It may be changed in the future depending on how Windows 10 support continues, but at the moment that date marks the death of IE11. As software engineers, we all know we’re not meant to like IE11. But why is that? And what are some practical solutions for its problems?

“This only occurs in IE11”

Most software engineers will probably have come across that phrase before. The most common (usually sarcastic) response is to tell the user to download a different browser. But what if they are part of an enterprise level company tied to some legacy third-party software that only works in Internet Explorer? Or maybe they’re a sadistic web developer who likes testing the work of others? Either way, there’s a strong chance that you will still have to support IE11 and to do that you need to understand why it’s different from other popular browsers and how you can avoid end users being affected by those differences.

Taking a look under the hood

The first step to understanding IE11 is understanding how browsers work in general. Browsers have an ‘engine’ which is responsible for rendering web pages, from parsing the HTML and CSS to painting the screen.

The main browser engines are:

Used by Safari
Used by Firefox
Used by Chrome and any other Chromium-based browser (e.g. Opera, ‘new’ Edge, Brave)
Used by Internet Explorer
Used by ‘old’ Edge

Different browser engines mean different ways of interpreting HTML and displaying it on a user’s screen, which is why the same site may appear differently across multiple browsers.

As well as the engine that is responsible for rendering, browsers also have a dedicated JavaScript engine. This is responsible for parsing and running the JavaScript code which is served in the browser.

The main JavaScript engines are:

Used by Safari
Used by Firefox (and developed by Brendan Eich, the creator of JS)
Used by Chrome and any other Chromium-based browser (e.g. Opera, ‘new’ Edge, Brave)
This is also the JS engine Node uses
Used by Internet Explorer
A fork of Chakra
Used by ‘old’ Edge

A different JavaScript engine means different interpretations and levels of support of the same source code.

Get some standards

By this point you might be thinking: “Okay so there are different engines but why don’t they all just work the same way”. I get it, we’re engineers, we like standards. Thankfully, you’re not the first person to think that.

In the late 90s, Netscape and Microsoft were battling it out for control of the browser market. Both were attempting to get the upper hand and their standards support was diverging rapidly to the point that it was near impossible to develop a website that was compatible with both companies’ browsers. Then came the ‘Web Standards Project’. Founded in 1998, this grassroots coalition of web designers and developers worked to ensure that browsers supported the standards created by the World Wide Web Consortium. Without the Web Standards Project, the modern landscape of web browsers might have looked a lot different than it does today. Over the years, Internet Explorer won over most of the market share thanks to the popularity of Windows. Each new version brought it closer to being compliant with the W3C standards.

Then in 2015, Microsoft came out with their new browser - Edge. This was to replace Internet Explorer 11 as Windows default browser and would have an all new browser engine (EdgeHTML) and JS engine (a fork of IE’s Chakra). In 2016, Internet Explorer was made End Of Life. This effectively means that technical support and security fixes will still be provided but there will be no new features added. That is how we find ourselves in the position we are in today. IE11 is able to support virtually all of the ES5 feature set but there will be no ES6 support added to IE11.

It’s worth mentioning that Edge was recently rebuilt as a Chromium-based browser, meaning that it now uses the same browser and JavaScript engines as Chrome. However, that’s not to say that ‘old’ Edge had weak standards support. Its final version had roughly the same ES6 feature coverage as Firefox and Chrome.

Rendering issues

The most likely issue you would encounter with different rendering in IE11 is due to some specific CSS not being supported. For example, IE11 does not support the ::placeholder pseudo-selector which allows you to style the placeholder text in inputs and textareas. You may also encounter some CSS bugs which have not been fixed, such as those surrounding the flexbox display type.

These CSS issues are a lot more common in Internet Explorer versions before 11. Unfortunately, there aren’t many catch-all rules for avoiding these and most of those encountered in IE11 are solved by using case-specific CSS workarounds.

JavaScript issues

You’re much more likely to encounter issues with support for certain JS features, considering that IE11 does not support most features newer than ES5. There are a number of such issues that we’ve run into here at Administrate. One I’ve personally encountered was the use of the ES6 Number.isInteger() method. I picked up a ticket for a bug with an error message which identified a line containing this function call, which was only occurring in IE11. This was a big red flag. I checked caniuse and was able to confirm that Number.isInteger() is not supported in IE11.

The caniuse site is a great resource for checking the browser support of code when debugging potential browser-specific issues. MDN also offers a browser support table for specific features, as well as polyfills for those features. A polyfill is a piece of code used to provide modern functionality on older browsers that do not natively support it.” These offer a way to mimic specific features that would not normally be supported by IE11.

An example of a Number.isInteger() polyfill is shown here:

Number.isInteger = Number.isInteger || function(value) {
  return typeof value === 'number' && 
    isFinite(value) && 
    Math.floor(value) === value;

It first checks to see if the method is defined and supported natively, if so then it is left untouched. Otherwise, it assigns an alternative function which provides the same functionality.

At Administrate, one of our core values is to be sustainable. Manually including polyfills in our code, like the one above, isn’t a very sustainable way to ensure we have good browser support. Instead, you could opt to use a service such as which accepts a request for a set of browser features and returns a minified bundle of the polyfills that are required by the requesting browser. Another option is to use a library such as core-js, which (amongst other things) includes polyfills for the most commonly used JS features.

Another solution is to use a transpiler, such as Babel. Transpilers take source code written in one language and convert it to another. A transpiler can take a JavaScript file written using ES6 features and syntax, and convert it into ES5 code that can run on Internet Explorer. Babel is a popular transpiler and at Administrate we use it alongside webpack to transpile our JavaScript code, even though most new code is written in Typescript which comes with the added benefit of already performing transpilation. The TypeScript ‘compiler’ can easily be configured to target ES5 which removes some of the headache of configuring Babel and Webpack.

Another approach that developers have taken towards supporting IE11 is simply not to do it. This is a stance that a number of companies have taken in order to force users to update to a current browser, but it may not be viable for everyone. For companies with a lot of enterprise customers (such as Administrate), pushing them to switch everyone over to a browser such as Chrome or Edge can be a slow and difficult process.

In the meantime, I hope that this blog post has given you a better understanding of what your options are to improve your IE11 support. See you all at my ‘End of IE11’ party on 9th January 2029!