Stop Nagging Your IE Users. They Get It Already

This week, that grand old bane of a Web developer’s existence—IE6—turned 12 years old. Like any tween, it has been subjected to bullying over the years. A year an a half ago, Microsoft finally took the step toward beating it to death by forcing updates to IE8. And they were widely successful. I go months both here on my little slice of the ‘net and on larger sites maintained by my employer without seeing IE6 pop up in the logs.

So, we’ve turned our attention to bullying its younger sibling, IE7, which turns 7 in October.  Again, those users should have been upgraded to IE9 as part of the Microsoft push, but a few computers still linger. We continue to bully. Some of us even go after four-year-old IE8 when it tantrums over our attempts to use CSS3 and HTML5 (or are we throwing those tantrums?).

Our favorite tactic seems to be telling users to update their browser with imposing messages (standard in templates like HTML5 Boilerplate directing them to browsehappy.com). Some people go farther to redirect to a special page entirely (*cough Jeff Starr*).

Why do we do this? Sure, it’s great to not have to do ugly things to our code to make those browsers display beautiful designs, particularly when our clients won’t listen to why websites don’t need to look the same in every browser.

It’s awesome to have fewer configurations to support for web applications.

We get to show off and go on a power trip, yelling “mwahaha, I refuse to bow to your ancient browser demands, I am all powerful, and I decide what you should use.”

But, what we don’t consider in these decisions is the user.

After more than half a decade, and after Microsoft has tried forcing upgrades, we have to ask why these users are still accessing our sites with browsers that should be a distant memory.

The reason is likely that they have to. For one reason or another (options too myriad to list here) they HAVE to use those browsers. It’s highly unlikely that a user on IE6 or IE7 doesn’t realize that they are using an outdated browser at this point in 2013.

So, why are we bullying our visitors? Why are we telling them that every time they visit our site that we think they don’t deserve to read our content because they have an old browser?

Other than attempting to alienate visitors, I can’t come up with an answer to that.

I’m not saying that we need to care if the design is broken (we don’t). I’m not even sure we need to care if interaction is half-broken. But we should care that our visitors have been reminded about using an old browser countless times yet they continue to do so, and that ultimately they just want to access our content.

So, why not let them access the information we’re providing without reminding them that they are second-class internet citizens? Really, what do you have to lose?

N.B. Yes, I know, pot, kettle, black. I have one of those notices on this very site. I’ve been running this design for over four years now, and a lot has changed in the landscape since then (I think those notices may have been valuable before Microsoft’s auto update move), but my lack of time to set up a redesign has not. Moving forward, though, I’ll be practicing what I post.

IE Change Event Delay

The Web is ever changing, and this article is relatively ancient having been published 8 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

I recently developed a sign-up form for a client that includes on-page price total calculation using JavaScript (jQuery). The premise is simple: the user provides information and specify options, then clicks a radio button to choose a specific price plan. The initial total price calculation is triggered by the change() event for the radio button elements. But, the client was concerned (and with user testing, it turned out rightly so) because in IE, the price calculation didn’t happen until the user clicked somewhere else on the page. In cases where they first clicked one option, then a different one, the price would seemingly lag behind because of IE’s delayed change event firing. It was confusing to the user, but worse—confusing for me to “fix” IE’s implementation.

The awesome news is that this has been fixed in jQuery 1.4, but the concern is still valid for older versions (which my application was using) and straight-JavaScript implementations.

The problem

In Internet Explorer, the change event fires when focus leaves the form element (an event know as blur). That means that the event happens only once a user has clicked on—or used the keyboard to navigate to—another element on the page (form or other).  In cases like mine, where a user is expecting instant feedback to their click, this causes issues with user experience. Unfortunately, this isn’t exactly a “bug,” as it’s how IE handles this event in 6, 7 and 8.

In other browsers—Firefox, Webkit-based (Safari/Chrome) and Opera—the event fires off immediately, so in order to have consistent, intelligent operation, we have to hack IE’s basic behavior. The easiest solution is to bind your function to a different event, such as the click event, but that’s generally not the right solution. There is a better one.

Why using the click event is wrong

One word: accessibility. Users—whether they have a disability that restricts their use of the mouse or like to tab about the page with the keyboard for speed—don’t always use the mouse to move from form element to form element. So, if you bind your functionality to the click event, you may end up messing with a user’s workflow, which makes for unhappy visitors. In some cases, it may even make a user unable to use your application. So don’t use that as your solution.

The real solution

If IE needs a blur event to know that the change event should fire, give it one when the element is clicked. In jQuery, that looks something like:

$("#element").click(function(){
	// In IE, we need to do blur then focus to trigger a change event
	if ($.browser.msie) {
		this.blur();
		this.focus();
	}
}).change(function(){ actionIWantOnChange(); });

This code tricks IE into thinking that focus has been changed away from the element when it is clicked. But since the change event is also triggered, the actions attached to that event also happen. Keyboard navigability still works, because even though there is no click, the change event will fire when they use the keyboard to move to another field meaning the feedback is instantaneous.

Now, you can probably improve my above example by using better feature-sniffing to test for IE instead of the browser object in jQuery, but my time for creating a fix was limited—and this code gets the job done.

The TITLE element and jQuery’s text() function

You’re doing it wrong. In a day of zero fun, a coworker and I ended up tasked with debugging a jQuery-based script that seemed to be perfectly fine, except of course, the part where it wasn’t working as expected in IE. After some tracing, it turns out the issue had everything to do with one line of code not returning a value: $("title").text();. To translate, the author of the code had been trying to retrieve the text of the title element using jQuery’s text function. But, turns out that doesn’t work in IE.

The solution

If you want to retrieve the value of the page title, use document.title. If you want to set the value of the page title—the title displayed at the top of the browser—use document.title.

It doesn’t matter if you’re working with straight JavaScript or a library like jQuery, the correct way to interact with the page title is through document.title.

Here’s a full code example:

var foo = document.title;
alert("The title was "+foo);
// on this site, the above alert would read
// "The title was The TITLE element and jQuery’s text() function"
document.title = "Now it’s been changed.";
alert(document.title);
// this alert = "Now it’s been changed"
// the display at the top of the browser changes too

The explanation

Don’t worry, I’m not going to leave you high and dry without explaining why the original approach didn’t work.

The problem exists in IE because IE doesn’t consider the title element to have child nodes. By W3C specs, the title element contains one, and only one child node: a text node. It can not have any child elements. Just the one text node.  But according to IE, that text exists in some strange nebulous state outside of a normal text node. Here’s a code example.

var titles = document.getElementsByTagName("title");
var kids = titles[0].childNodes;
alert(kids.length);

If you run that code in IE, the alert will be 0. In FireFox, Chrome, Safari, Opera, etc, it will return 1, the expected amount.

Breaking down jQuery.text()

So, the reason $("title").text() doesn’t work in IE is because of jQuery.text()’s reliance on children nodes. Let’s take a look at the function (jQuery version 1.4.2, line 3418):

function getText( elems ) {
	var ret = "", elem;
	for ( var i = 0; elems[i]; i++ ) {
		elem = elems[i];
		// Get the text from text nodes and CDATA nodes
		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
			ret += elem.nodeValue;
		// Traverse everything else, except comment nodes
		} else if ( elem.nodeType !== 8 ) {
			ret += getText( elem.childNodes );
		}
	}
	return ret;
}

A quick translation of the code is as follows. The first line of the function sets up a variable ret as an empty string. This variable is the return variable for the function. Then we jump into a loop that goes through each object in the array that was passed in (remember, $("title") will return an array with a single element). For each of these elements it checks whether it is a text node. If it is, it appends the node’s value to the return value (ret). If it is an element, it recursively calls itself on that element, appending the result of the recursive call to the return value. At the end, ret is returned.

But, remember, in IE, the title element has no text node, because there are no child nodes. So what does ret equal? An empty string. The entire for loop is skipped, because elems is empty. It essentially goes straight from declaring ret="" to returning that initial value.

The code continues to work in other browsers because they rightly treat the element as having a single child node—a text node— and that node’s value—the text—is added to ret.

innerText doesn’t work either

Even if you’re using plain JavaScript without a a library, document.title is the way to do this. Typically, to set the text of an element in IE you would use the innerText property, but you shouldn’t do that in this situation. There are a couple reasons for this:

  1. It doesn’t work in IE. In fact, it’s a documented issue dating back to IE 5, maybe earlier. At this point, we have to assume Microsoft has it working as they intend it to.
  2. The innerText property doesn’t work cross browser. In FireFox, you have to use the textContent property. Why bother writing extra code to be cross-browser compatible when document.title will work without issue?

Wrapping it up

Here’s that first script again, showing the correct way to do it:

var foo = document.title;
alert("The title was "+foo);
document.title = "Now it’s been changed.";
alert(document.title);

So now you know why you can’t use jQuery.text() to retrieve the page title. But that’s ok, because doing so would be inefficient anyway when you can just call document.title. Good luck with your dev.

IE Gradient Bug with PNG-24

The Web is ever changing, and this article is relatively ancient having been published 9 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

I try to make sure to do my due diligence by checking my sites in the 3 major browsers. And usually, much to my chagrin, I also end up thoroughly testing in IE6, although I’m not willing to make them pixel perfect unless I’m being paid very well to do so. So, I was extremely surprised when I client got ahold of me about a display bug in a now live site. Ok, so you have to believe me, I really did check in IE7. On multiple computers. I don’t know why the client’s installation was special, but sometimes that’s just how things go.

The problem

Demo of problem

This isn’t the actual client site, but you get the idea.

The solid-color slightly-transparent drop-down menu backgrounds were showing up as 80% alpha gray to completely transparent gradients, thus rendering most of the navigation illegible.

Code Foundations

These were pretty run-of-the-mill drop-down menus comprising

  • semantic, nested uls, with
  • CSS-styling, including hover states (where available), topped with
  • jQuery/Superfish enhancement,

although I was trying some CSS3 with the styling.

The CSS wasn’t anything for beginners although it’s nothing crazy. To start with, my backgrounds were transparent by way of RGBa background-colors for browsers that support it. Then it downgraded to a opaque grey for older versions of modern browsers/non-IE browsers. And then, in the IE-only style-sheets I swapped in a 1×1px PNG-24 w/ alpha transparency (which was being fixed by DD_belatedPNG in IE6).

Ok, no problem so far. When I tested in IE6/7 my background image swapped itself in and repeated and everything looked fab.

Except for on the client’s computer.

The Cause

After much Googling that turned up very little, I found some promising complaints about pngs going wonky in IE if they’re stretched. Then I was super confused. You can’t stretch a background image with CSS. But to keep it simple: for some reason, the JavaScript was hijacking my background-repeat and instead was scaling (stretching) the png, under certain circumstances. And voilà! seemingly-unexplained, phantom, uncoded gradients.

The Solution

Make the PNG 2×2px or 800×1px or … well, you get the idea. IE doesn’t always play nice with 1×1px PNG files with alpha transparency. Who knows why, it just doesn’t. But it’s an easy fix. Unless you want to complain about file size. But then you better go off and make me a gorgeous background sprite so you’re not killing your visitors with a bazillion extra HTTP requests if you know what’s good for you.

Closing Arguments

In short: if the background image is getting stretched, just change from 1×1px to something larger.

Also, please don’t murder the teacher, advanced kids. I realize that my implementation also had some kinks that should be ironed out, but this post is just about those damn PNGs.

IE Bug on Enter Key Form Submission

The Web is ever changing, and this article is relatively ancient having been published 10 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

Due to a punishment handed down by the gods, I’m forced on a weekly — if not daily — basis to serve and protect the ridiculous number of Web users who haven’t escaped the dark ages. Yeah, that’s right — I have to bug hunt in IE6 — a browser with many documented bugs that is quickly approaching its eighth birthday. And sometimes those funky bugs exist even in IE7. This is one of those stories.

The Problem

One of my recent projects was setting up an extremely simple app for a local company. They gave out fliers with a URL and a short alpha-numeric key to students at local schools. The purpose was to have the students go online to the URL and enter the key to access some school-specific information.

Extremely simple and quickly completed, until I was testing and found out that IE didn’t pass along the submit input value if the user submitted the form by pressing enter. Forms 101: enter submits the form, including the submit input.

So why was IE failing remedial form submission? Why, another IE bug of course. And not a very well documented one.

View a Demonstration

When Does it Happen?

Example of problematic form

Think this is a quick, simple, easy form? Not quite …

This bug rears its ugly head under the following conditions:

  1. Your form contains one, and only one, text input. (It can still have other types)
  2. Your visitor hits enter to submit the form while not focusing on a checkbox, radio, or the submit input (in other words, most likely only if they’re focusing on that single text input or some esoteric input element).

The Solution

This issue throws us into a bit of a grey area in terms of a solution, because frankly, there’s no magic fix. But, there are a few different workarounds that you can use. There are various ways you can do it with Javascript, of course. But that means the form can’t be submitted with the bug fixed without JS enabled, thus I’m not going to explain those methods.

Probably the best solution is the one Jim Meyes posits:

The solution is to hide an additional disabled input for IE to find, using IE conditional Comments and hiding it from view with some CSS.

<!--[if IE]><input type="text" style="display: none;" disabled="disabled" »
	 size="1" /><![endif]-->

Editor’s note: Line breaks marked by ».

Why this is a good solution

This is extremely unobtrusive (and thus a quality solution) for a few reasons.

  1. Only IE will “see” the extra input, so we’re not fixing anything that’s not broken in other browsers.
  2. Because the field is disabled, the value isn’t getting passed through to the processing scripts when the form is submitted, so it’s not going to get in the way in the backend.
  3. This might be the only case in which I advocate for inline styles, but they’re solid here, because even if there is a user-specific stylesheet enabeld, it’s unlikely that a style will take precedence unless !important is employed (and IE <= 6 ignores that declaration anyhow …)

The only case I can think of where the user will notice this is when CSS is disabled (and far more unlikely: if for some reason a screen reader or such doesn’t ignore display:none;). My only suggested improvement: add a value to the field that succinctly describes why the field exists and is disabled. Thus, I would use this code:

<!--[if IE]><input type="text" style="display: none;" disabled="disabled"  »
	 size="20" value="Ignore field. IE bug fix" /><![endif]-->

Editor’s note: Line breaks marked by ».

N.B. I also bumped up the size of the field so that the visitor could see the entire value. This shouldn’t be a problem; if they’re actually seeing the field, your layout is already mangled.

Can you think of a better workaround?

Closing Arguments

Basically, if you are doing any server-side processing that relies on checking to see if the submit button was pressed, you must have multiple text fields or implement a workaround.

Best of luck in your own IE bug hunting. And please, wear bright colors and don’t shoot other hunters.

Update: I haven’t tested it personally, but I’ve received a few comments and e-mails that it also happens in IE8. So, maybe it’s not a bug, but it is an annoying decision on Microsoft’s part. This hack works, at least.