New here? Start with the essentials and go from there.

Wednesday, May 6, 2009

IE7 Fun Fact: Cannot calculate percentage of absolute element

We all know that IE6 has trouble doing percentage heights and widths of implicitly-sized elements, and also that it does not accept, say, “top: 0; bottom: 0;” on an absolutely-positioned element to give it the height (including padding) of its container. IE7 fixes both of these bugs, but still has a problem with the combination.

Here’s the example:


There’s an outer red element (positioned absolutely with top, left, bottom, and right at 0) that should be entirely obscured by the green element, which is statically positioned with height of 100%. In IE7, however, the green element is only as tall as the line height.

IE7 is unable to calculate the percentage (“100%”) of an absolutely-positioned element that is sized by setting its top / left / bottom / right properties. Unfortunately, it appears that no combination of hasLayout or overflow or anything will sort this out.

The solution is to sully ourselves by resorting to the ultimate hack, an expression.

When we add the following code, IE7 behaves:

height: expression(this.parentNode.clientHeight)

Unfortunately, parentNode.clientHeight and height: 100% are not equivalent when the parent has padding. clientHeight includes it, whereas the percentage does not (when the element is positioned statically, that is).

Here’s a padding example, which should have a nice five pixel red border around it.


Solving this entirely correctly with an expression is not really practical, as it will require looking up calculated styles and the like. Nevertheless, we can cheat if we assume that the container’s padding will be symmetrical. We then just say:

height: expression(this.parentNode.clientHeight - 2 * this.offsetTop)

As long as the top and bottom padding are the same (offsetTop is an effective measure of the top padding) this will look ok:

Fun Fact: “100%” differs between static and absolute

This one surprised me a little bit today. Take a look at these two divs:



The outer, red element is 150px square, with a 10px margin and a 10px padding. The inner, green element has width and height of 100%. The left one is positioned statically, while the right one is positioned absolutely.

For a statically-positioned element, “100%” means the parent’s inner width and height, while for an absolutely-positioned element, “100%” means the parents width and height including padding.

Wednesday, July 2, 2008

IE Fun Fact: getAttribute of form action doesn’t work

Given the following HTML:
<form id="form" action="servlet.do">
  <input type="submit" name="action" value="Add" />
</form>
How does one get the value of the form’s action attribute? form.action is of course right out, as that returns the <input> node. But what about:
var form = document.getElementById('form');
var action = form.getAttribute('action');
Makes sense, no? It turns out that this doesn’t work in Internet Explorer. In IE, the result of the getAttribute call is still the <input> node.

The solution, as described in this forum (thx, MHenke!) is to dig into your DOM reference book and use getAttributeNode instead:
var form = document.getElementById('form');
var action = form.getAttributeNode('action').value;
And good times were had by all.

Explanation of binding in JavaScript

A List Apart has a new article about JavaScript binding. If you don’t already have a solid appreciation for the fact that the this keyword in JavaScript does not work the way you would expect from Java, it might be worth giving the article a read.
In JavaScript, binding is always explicit, and can easily be lost, so a method using this will not refer to the proper object in all situations, unless you force it to. Overall, binding in JavaScript is not a difficult concept, but it is far too often ignored or glossed over by JavaScripters, which leads to confusion.
That being said, you may need to already be comfortable with first-class functions to totally grok it.

Also, I was somewhat disappointed by the statement:
Such a closure will be maintained by the JavaScript runtime no matter what, so there is no extra cost to using it. Even if there were, I’m fairly confident that it would be far less than the cost of an extra function call at every turn of the loop.
I’m poking around now to see if I can find real performance numbers for bind() vs. lexically binding this. The words “fairly confident” are a giant red flag in any optimization discussion.

Wednesday, June 11, 2008

IE Fun Fact: "disabled" not supported for <option>s

Select, Option, Disabled And The JavaScript Solution: “As I mentioned recently, there is a bug in Internet Explorer that stops you from disabling options in a select/dropdown element.”

Yes, that’s right. You cannot disable a menu item in a <select> box in IE6 or IE7. The above post goes on to list some failed attempts at a solution before coming up with something that works, involving listening to onchange and correcting selections of disabled items.

Hat tip to Jason for getting bit by this.

Friday, May 23, 2008

IE Fun Fact: cssFloat vs. styleFloat

I’m a bit embarrassed that I didn’t already know this cold, but I found out today that not only is the “float” style attribute called “cssFloat” in JavaScript, it’s called “styleFloat” in Internet Explorer.

From JavaScript tutorial - DOM CSS:
The only odd style is float, which is a reserved word in many languages, including JavaScript. As a result, the float style must be set using cssFloat in standards compliant browsers, and styleFloat in Internet Explorer (some standards compliant browsers also provide this as well). Simply set both of them. It will not cause any problems, and will work in all possible browsers.
In other words:
var floatValue = el.style['cssFloat'] || el.style['styleFloat'];
el.style['cssFloat'] = 'right';
el.stlye['styleFloat'] = 'right';

Monday, May 19, 2008

How To Attack An Internet Explorer Display Bug

I just mentioned this in today’s fun fact about zoom: 1, but it’s good enough that it deserves its own post: How To Attack An Internet Explorer Display Bug.

Read the whole thing, as they say. (Executive summary: use position: relative and, if that doesn’t work, move on to forcing hasLayout.)