Four browser notes

In case you’re wondering why this blog is updated so rarely; I’m taking a slight break from web development, and I’m working on a major upgrade of my Dutch politics section. It’s not ready yet; I’ll let you know when it is.

However, while working on it I found a few browser peculiarities, and I thought I'd let you know. There’s one IE bug; one case in which IE does the right thing and the other browsers don’t; the third is a Chrome peculiarity (not a bug); the fourth is an undocumented property in Opera.

Opacity in IE8-as-IE7

First of all, I found a difference in opacity handling between IE8 in IE7 compatibility mode and a true IE7.

In IE7 (both pure and IE8-as-IE7), opacity is set as follows

.opaque { filter: alpha(opacity=50); }

In IE8, on the other hand, opacity is set as follows (and as far as I understand this is a temporary solution on the way to proper opacity support):

.opaque { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; }

I needed opacity for some of the nice political maps I’m preparing, and did the following:

.opaque { filter: alpha(opacity=50); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; }

Works fine in IE8, and in IE7. But not in IE8-as-IE7.

It turns out that you have to swap the lines; apparently IE8-as-IE7 gets confused when the -ms-filter follows the filter .

.opaque { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; // first! filter: alpha(opacity=50); // second! }

That’s one more bug solved (and I notified the IE team), but it set me thinking. Do we have to pay any attention to IE8-as-IE7?

Test in IE8-as-IE7?

This is probably as good a place as any to remind everybody how IE8-as-IE7 works.

By default, IE8 renders pages with the IE8 rendering engine. (We had a frightful argument about this at the start of the year.) However, the website author can order IE8 to use the IE7 rendering engine instead by adding a <meta> switch to all pages, or to the HTTP headers: <meta http-equiv="X-UA-Compatible" content="IE=7" /> Furthermore, IE8 allows the user to switch to the IE7 rendering engine by pushing a button next to the location bar. (Note that this button is only present if the current site has no <meta> switch. If it does, the switch is obeyed and the user cannot select another rendering engine.) Fortunately, IE remembers what rendering engine you use for a certain site. If you decide to use IE7 compatibility mode to view QuirksMode.org, that mode is used every time you return to it. If you surf to another site without a <meta> switch, IE8 initially returns to IE8 mode, although you can still overrule that by pressing the button again.

In the absence of a <meta> switch IE allows you to select a rendering engine on a per-domain basis. This is good to know (I didn’t test this before).

So when it comes to your visitors you can ignore IE8-as-IE7; they will always see your site in IE8 mode initially, and if there’s no reason to switch they won’t press the button and remain in IE8 mode forever. (At least, that’s what I think will happen. We’ll have to see how users react to the presence of the button.)

However, IE8-as-IE7 is also useful to web developers. Eventually, you won’t have to install any IE version except for the latest. It will contain all previous versions (except IE6) in compatibility mode, and testing your website in such a mode becomes a simple matter of temporarily adding a <meta> switch.

Add switch, test site, make changes, remove switch (or switch to yet another compatibility mode). Cool.

But for this scenario to work properly, IE8-as-IE7 (and future IE9-as-IE7 etc.) will have to emulate a “pure” IE7 perfectly. With the opacity bug, that’s not quite the case, and that’s why it’s so important to test IE8-as-IE7 for bugs.

So I’d like to suggest testing your sites in IE8-as-IE7 for the moment, and comparing them to a pure IE7. Any bug you find will help the IE team. It’s certainly what I’m going to do in the next few months.

HTML: IE gets it right

While working on the same site, I found a curious difference between IE and all other browsers, and contrary to the usual state of affairs IE gets it right, and all other browsers get it wrong.

In my politics site I want to be able to embed nice graphs and maps in the main text wherever I want. So I devised a system of tags:

<include type="parliament" year="1967" />

This embeds a graph of the 1967 Dutch parliament in the text, at the indicated spot. I wrote the script, tested in in all browsers, and it works. Cool.

However, I ran into serious trouble when I wanted to do some cleaning-up of the DOM structures. I intended this <include /> tag as a kind of data-island; a construct that is either interpreted by the script or ignored completely but doesn’t influence the rest of the page and forms a separate DOM element.

Unfortunately, all browsers interpreted it as an opening tag, and placed all subsequent content within that tag. In the snippet below, I intended the two paragraphs and the <include /> to be children of the same parent node.

<p>Yaddah yadday yah. Yaddah yadday yah. Yaddah yadday yah. Yaddah yadday yah.</p> <include type="parliament" year="1967" /> <p>Yaddah yadday yah. Yaddah yadday yah. Yaddah yadday yah. Yaddah yadday yah.</p>

Instead, what browsers did was make the second paragraph a child of the <include /> .

Except for IE. Only IE obeyed the closing slash and did what I originally intended; only IE made the <include /> a sibling of both paragraphs.

Right now I’m in bitching phase; I’ll probably cave in and add </include> tags later on. But how I wish the other browsers understood the closing slash. (And I am using an XHTML doctype, so they’re supposed to know what a closing slash means.)

Appending to a paragraph

On a related note, I once made an HTML error that led to frightful errors in IE; and again it turned out that IE is right and the other browsers are wrong in not showing the error.

<p>Yaddah yadday yah. Yaddah yadday yah. Yaddah yadday yah. Yaddah yadday yah.<p> <include type="parliament" year="1967" />

Note that I accidentally forgot the slash in the closing </p> . This error made the <include /> a child of an otherwise empty <p> .

IE threw an Unknown Runtime Error; the other browsers executed the script correctly. After thinking about it, I decided IE was right and the other browsers were wrong.

Each of the graphs JavaScript produces has a container <div> as topmost element. This <div> is inserted into the page just before the <include /> , and the script appends the actual graph to it. In this particular case, they append a <div> to a <p>

The point is, a <p> element is the lowest block-level element there is. It cannot contain other block level elements; only inline ones.

IE obeys that rule. It refuses to append a <div> to a <p> , because that’s not allowed. All other browsers ignore the rule and append the <div> . They’re wrong.

Chrome: looping through object members

Take a JavaScript object and loop through it:

var myObject = { "member1": "yaddah", "member2": function () { return "yaddah" }, "member3": ["yaddah","more yaddah"] } for (var i in myObject) { alert(i); }

All browsers will alert "member1", "member2" and "member3", in that order. They follow the source code order of the members.

Chrome doesn’t. It will loop through the object members in what appears to be a random order.

Now this is not a bug. Every JavaScript book (including my own) states that JavaScript interpreters may loop through the members of an object in any order they want.

Parts of my script relied on the browsers looping through object members in source code order. While writing them I knew I was doing the wrong thing, but I thought “Ah well, all browsers do what I want anyway.” Not so. I have to add an array that contains the member order.

This is one of the most tricky areas of browser compatibility. What counts for more, the formal specification or the practical implementation by all browsers?

If the change is relatively easy to implement, I would suggest the Chrome team follow the lead of the other browsers and loop through object members in source code order. I can’t force them spec-in-hand, though; the specification clearly gives them the option to retain the current behaviour.

Opera: the text property

Finally, Opera turns out to have a text property for all DOM nodes (or at the very least for all <div> s). This throws my graph creation script off, because it sometimes stores information in the text property. Opera shows that information on screen. All other browsers properly hide it until the right time has come.

The solution is simple: use a different name for my property. Nonetheless, I wish Opera had documented this proprietary feature.

Comments are closed.