Working With Internet Explo{d,r}er 9

Lately I’ve been working with Web Components in my spare time and recently I was moved to the Engineering group at 3Pillar. At work I have been challenged by the limitations of Internet Explorer 9 (IE9). Many of our clients still support browsers like IE9 and much of the corporate and government world use browsers that have been locked down to certain versions either because of the Hacker News propaganda and paranoia with security/privacy issues in browsers or just because ‘Big Brother’ said so. In fact, the corporate world seems to prefer the ‘security’ & ‘privacy’ of Internet Explorer. Many features in browsers that are not named ‘Internet Explorer’ are disabled and system administrators will sometimes lock down everything ‘just to be sure’. Internet Explorer itself gets locked down as well. Perhaps it is the “clear” internet options that integrate so well in their ‘secure’ windows environment.

Now that I am part of the Engineering group I have client work that has a real need to work with older browsers as opposed to the cutting edge prototype work I was doing previously with the User Experience group. It has been a while since I had to break out my cross-browser bug smashing mind and I was very excited that I did not have to worry about IE9’s cleverly named predecessor – Internet Explorer 8.

Some of the pain I encountered in IE8 has been extreme and frustrating to say the least. At first I compared it to IE7 and justified the abuse much like a battered victim would. After all, it supported CSS data-uri’s, I had no more float or double margin issues, hasLayout worked a bit better….I am sure there is more but that’s about the sum of it. IE8, like it’s father before him, had extreme issues with lazy loading and script performance. Internet Explorer 8 and older versions have been using JScript, which is a variant of JavaScript that is non-standard and proprietary to Microsoft. IE9 is the first of the IE browser family to use standard JavaScript.

Internet Explorer has had a history of CSS issues solved with expressions filter rules. These work but are highly toxic to performance. Rendering times are significantly higher when using these, so don’t if you can help it.  The most obnoxious piece of IE8 (and IE7) with regards to CSS are it’s request and file size limitations.

Internet Explorer 7

  • Maximum Stylesheet Size Limit: 288kb per file
  • Maximum number of CSS Stylesheets:  30 files.

Internet Explorer 8

  • Maximum Stylesheet Size Limit: 288kb per file
  • Maximum number of CSS Stylesheets:  30 files.

Internet Explorer 9

  • Maximum Stylesheet Size Limit: not tested yet
  • Maximum number of CSS Stylesheets:  30 files.

Internet Explorer 10

  • Maximum Stylesheet Size Limit: not tested yet
  • Maximum number of CSS Stylesheets:  not tested yet

Other limitations that are less significant with regards to CSS are the rule counts, import counts, and import nesting levels. While these numbers may seem unreachable – consider the misuse of CSS Preprocessors on a team of 20-30. It has happened before and hopefully we are now writing CSS in a style like OOCSS or SMACSS to avoid this.
Internet Explorer 6-9

  • A sheet may contain up to 4095 rules
  • A sheet may @import up to 31 sheets
  • @import nesting supports up to 4 levels deep

Internet Explorer 10

  • A sheet may contain up to 65534 rules
  • A document may use up to 4095 stylesheets
  • @import nesting is limited to 4095 levels (due to the 4095 stylesheet limit)

The worst part about these limitations is that no errors or information is sent to the users. In fact, when Internet Explorer parses a CSS file and reaches its maximum kilobyte size, it just stops parsing it. The request is still a 200 but suddenly some CSS rules are missing. When minifying and concatenating files, as current best practice would probably warrant, this becomes a debugging nightmare unless you know that these limitations exist.

IE9 has full support for SVG (Scalable Vector Graphics)! Prior to IE9, the browser used it’s own variant of SVG called VML. Charting libraries had limited support for VML so this is great that SVG is finally native in IE. IE9 also has full CSS support for Media Queries but that only includes CSS rules. Keep in mind that the JavaScript “window.matchMedia” method does not work. IE9 does not support “Element.classList” which is frustrating if you don’t want to use JQuery. IE9 does have partial support for Viewport Units which is helpful but not as flexible as we need. Pointer Events require a polyfill as they are not supported as well. Combine that with bugging CSS Appearance rules and styling form elements still sucks really bad. As far as layout goes, I have had no luck getting Flexbox polyfills to work in IE9 so “display: table” or floats seem the only semi-sane way for go. IE8 and IE9 have issues with cross origin resource sharing & CSP as well. The typical scenario occurs with icon fonts from Google Fonts are not loaded but cross domain issues are not limited to this particular case. IE8 & IE9 get buggy partial support for this using ‘XDomainRequest’ and the majority of polyfills require you have access to the origin server…gee, that’s useful.

To Sum up…IE9 IS the new IE8. Like IE8, it adds a huge amount of development overhead when developing for rich and performant applications. Consider burying it alive if you can. Here are some tests to visualize some of the CSS issues.

Advertisements

LifeCycle Callbacks in Custom Elements

I was going through the HTML5 Google Community posts a few days ago and saw Max Waterman had asked a question about  Custom Elements. I thought I could easily answer this one, so I did. Interestingly enough I learned a bit more as I answered the question. When I was going through code in the console to test I noticed a few things I hadn’t before.

// namespace for custom elements
var customElements = {};

// create a JavaScript object based on HTMLElement
var registeredElementProto = Object.create(HTMLElement);

//add a function to registeredElementProto
registeredElementProto.foo = function(){ return 'foo'; };

//add a property to registeredElementProto
registeredElementProto.bar  = 'bar';

//add a createdCallback
registeredElementProto.createdCallback = function(newBar){
this.bar = (newBar || this.bar);
console.log(this.foo() + this.bar);
}

// add our element to the DOM registry
customElements.fooBar = document.registerElement('foo-bar', { prototype: registeredElementProto });

Alright, this looks good so now I will add a instance of my element to the DOM using it’s constructor. Should be simple enough, right?

var myConstructor = new customElements.fooBar("Baz");
constructor error from custom elements

constructor error from custom elements

I spin the wheel and I can hear the sound of Pat Sayjak laughing at me as the spinner lands on a ‘Bankrupt’ space. What just happened here? Let’s take a look at the Lifecycle Callbacks a DOM Element. These are functions that are fired internally by native code but can optionally be redefined.

HTML Rocks description of Custom Elements

HTML Rocks description of Custom Elements

One thing that was unclear to me before was whether or not you can override these callbacks to take parameters from the element constructor.  Keeping in mind that “createdCallback” is not the actual element constructor I would guess that it is most likely just a simple callback fired by the containing element constructor. I would hope something similar to this might be the case.

//...
constructor (arg1, arg2,...){
// main constructor logic
this.createdCallback.apply(this, arguments);
}
//...

If I update the first code example so that I inspect the arguments of a redefined ‘createdCallback’ I see that no arguments exist. Notice I am adding an argument reference as well in ‘fooBarOne’ and no arguments in ‘fooBarTwo’.

// ...

//add a createdCallback
registeredElementProto.createdCallback = function(newBar){
console.log("args",  arguments, newBar);
}
// ...

var fooBarOne = customElements.fooBar('myArg');
//-> outputs TypeError: This constructor should be called without arguments.

var fooBarTwo = customElements.fooBar();
//-> outputs to console "args [] undefined"

I can see now that ‘fooBarOne’ outputs a type error “TypeError: This constructor should be called without arguments.” and as I would expect in ‘fooBarTwo’ the output in the console is an empty arguments object and the ‘newBar’ argument is ‘undefined’ even though I tried to override in the callback signature. Based on this, I would bet that when we define custom elements, the native code constructor will not recognize any arguments passed in and therefore even if redefining my callbacks with parameters and my assumption that callbacks would apply constructor arguments, the constructor never allows arguments to pass into the HTML Element anyway so nothing like this could work.

I guess it makes sense though since custom elements can also be constructed using ‘document.createElement’ which takes only only parameter which is the name of the element which happens automatically when calling “new ElementName();”. I’m a bit naive to browser development but I would guess browser developers would have to either redefine ‘document.createElement‘ and HTML Element constructors AND make it all backwards compatible, or they would have to further clutter DOM manipulation with a new function ‘document.createCustomElement’ & change the internals in the JavaScript ‘new’ constructor for HTML Elements as well.