/ IE 8

Must-have Tools And Hacks To Build A Modern Website That Support IE 8

Recently, I am asked to convert a modern website to be IE 8 friendly. It's the beginning of nightmare...because IE 8 IS NOT A MODERN BROWSER! How could it support a modern website? By then I have spent so much time debugging on IE 8. Hope this article can reduce your pain if you are doing the same thing.

Let's talk about some of the general problems, and the corresponding solution.


console.log()

IE 8 has native support for console.log(), but only when you have opened the console interface in Developer Tool (F12). Otherwise, it will throw an error and blocks other script execution because console is not defined.

Solution: Custom Console Functions

We will define console in the very beginning of page load before executing any other scripts.
Put the following script before all Javascript:

<script type="text/javascript">
(function() {
  var _dummyFn = function() {};
  var _console = {
    trace: _dummyFn,
    info : _dummyFn,
    log  : _dummyFn,
    warn : _dummyFn,
    error: _dummyFn
  };
  window.console = window.console || _console;  // use the default console if it is defined
})();
</script>

Media Query

@media screen and (max-width: 1023px) {
  .sidebar {
    display: none;
  }
}

Media queries are essential for developing a responsive website. For example, the above CSS hides the sidebar when the browser width is less than 1024px. Every modern browser supports media query, but IE 8 does not.

By default, responsive website are not for IE 8.

Solution: Respond.js

Respond.js is developed as a polyfill for browsers which do not support media queries.

Installation

// YOUR CSS FILES HERE

<!--[if lt IE 9]>
<script type="text/javascript" src="/includes/js/respond.min.js"></script>
<![endif]-->

Limitation

  • Only supports min/max-width media queries
  • The stylesheets must be loaded before Respond.js
  • The site is displayed improperly for a short while before Respond.js is executed
  • Does not work for in-page CSS (i.e. <style>...</style>)
  • Quite a few more, read the official site for latest updates :)

CSS3 Pseudo-classes

.row {
  background: #FFF;
  border-bottom: 1px solid #000;
}
.row:nth-child(even) {
  background: #DDD;
}
.row:last-child {  /* OMG! IE 8 supports first-child, but not last-child */
  border-bottom: none;
}

The above CSS will generate rows with alternating colors with a line-separator between the rows for all modern browsers - not IE 8, since many CSS3 pseudo-classes are not supported.

Solution: Selectivizr

Selectivizr will read your stylesheets and add custom classes to the DOM, which your CSS3 selectors targeted, to make the magic.

Installation

<!--[if lt IE 9]>
<script type="text/javascript" src="/includes/js/selectivizr.min.js"></script>
<![endif]-->

Limitation

  • Does not work for in-page CSS (i.e. <style>...</style>)
  • No effect on DOM created after page load
  • Quite a few more, read the official site for latest updates :)

Potential Issue

IE 8 may prompt "Stop Running This Script" warning if you have many CSS3 targeted DOM in the page. A fix was committed to the project but is never merged. You can use the fixed version forked from the official repo instead.


Repaint For DOM Manipulation

Problem 1: Does Not Repaint After DOM Manipulation

$(document).ready(function() {
  $('.floatLeft').height($('.floatRight').height());
});

The above script synchronize the height between the left and right floating container. It works in all modern browsers, but not IE 8, AGAIN. The reason is that IE 8 forgets to repaint after the inline CSS is inserted.

Solution: Adding Dummy Class

You can force the browser to repaint by adding a dummy class to the DOM.

$(document).ready(function() {
  $('.floatLeft')
    .height($('.floatRight').height())
    .addClass('for-ie')
    .removeClass('for-ie');
});

If you have many DOM manipulation, you can add the dummy class to the parent for better efficiency.

$(document).ready(function() {
  $('.row').height(100);  // set every row to have height 100px
  $('.table').addClass('for-ie').removeClass('for-ie');
});

Problem 2: Incorrect DOM Properties

function printDocumentHeight() {
  console.log($(document).height());
}

$(window).resize(printDocumentHeight);

It is weird that the document height does not align with the actual document height when the browser is resized. The reason is that IE 8 has not updated the properties at the time printDocumentHeight is called.

Solution: Delay The Manipulation

Delay the manipulation allows time for the browser to update the properties.

function printDocumentHeight() {
  console.log($(document).height());
}

$(window).resize(function() {
  setTimeout(printDocumentHeight, 10);	// delay the execution by 10ms
});

Too Many Stylesheets

IE 8 will throw Invalid procedure call or argument if there are too many stylesheets in your page. Although having many stylesheets in a page is probably a bad practice, you may find the following solutions helpful if you hit the error (Well, I hit it for one of the projects).

Solution 1: Concatenate All Your Stylesheet

Combining the tons of stylesheets into one or a few will do the magic. However, there may still be issues. Firstly, be aware that each stylesheet should not contain more than 4095 rules, or the same error will be thrown. Secondly, combining many stylesheets may be developer unfriendly, or you won't have so many stylesheets. Here comes to you Solution 2.

Solution 2: Use @import To Import The Stylesheets

While this solution avoids the pain for merging the stylesheets, it poses its own limitations. Firstly, the number of imported spreadsheets is still limited. Furthermore, Respond.js is not going to work for imported CSS lol. Last but not least, @import will slow down your page load.


Testing IE 8

After writing the code, you should test it eventually. I understand that you might not have an IE 8 on your machine, and the compatibility mode on newer IE is not reliable as well. We need a real IE 8 for testing.

Solution: Modern.ie

Microsoft provides virtual machines with IE 8 installed. You can download the images here and start testing on the virtual machine.

One thing to notice is that the Windows on the virtual machine is not activated. You should take a snapshot before the first boot up, and recover from the snapshot when the Windows expires.


Conclusion

IE 8 is not a modern browser.

Forcing it to support modern website is like teaching a kid to do maths - paying a lot of effort to tell 1 + 1 = 2. And since many hacks are Javascript, there must be a performance trade-off.