A workaround for using the :active pseudo-class with anchors in IE7

NOTE: This post is intended for developers frustrated with IE7’s lack of support for the :active pseudo-class. The information contained within has been noted in other articles, such as Jeff Starr’s Unobtrusive JavaScript: 5 Ways to Remove Unwanted Focus Outlines or Oscar Alexander’s How to Make Sexy Buttons with CSS, but I don’t think I’ve seen a post solely dedicated to this specific issue, so I figured I’d take the time to create one.

The Background

A little while ago, I set out to create a couple of image buttons. I wanted something that was reusable and had the potential to be used with ASP.NET with the least possible extra work/maintenance. I liked the design concept that the guys over at Wufoo have been using and decided to see if I could code something that would emulate that look and feel, particularly in regards to the way they used the :hover and :active pseudo-classes to add a touch of interaction.

So here’s an example of what I came up with:

Image

Here’s what that button looks like when the mouse is hovering over it (:hover):

Image

And here’s what it looks like when the user clicks on it:

Image

None of this is groundbreaking or terribly fancy, but it does the job nicely.

The Problem

The problem I noticed is that, in IE7, the :active pseudo-class seems to behave more like the :focus pseudo-class. That is, the CSS instructions provided in the :active pseudo-class should be presented only for the duration of the mouse click, but instead persist for as long as the anchor element has focus (focus is given to the anchor onclick). This may not be a problem in every scenario, particularly if clicking on the button results in a refresh or a redirect to another page. If the button in question is to be reused between page refreshes, however, then your users may end up wondering if it’s safe to continue when the button has not returned to its original state. In any case, it mildly degrades the user experience and, as such, it probably should be addressed.

The workaround I employed is quite simple. To each anchor tag, I added an onclick handler roughly equivalent to the following:

<a class="button green" onclick="this.blur();" href="#">Link Text</a>

That seemed to fix the problem. It also gave the added bonus in some browsers of eliminating the dotted border indicative of focus that appears post-click (but that may not be news to most people).

In case you were paying attention in the beginning of my post, you may recall that one of my goals was to create a solution that could be easily reused in ASP.NET. To do that, I’d simply use the LinkButton control in a manner similar to the following:

<asp:LinkButton ID= "myButton" runat= "server" CssClass="button green">
<img alt="" src="img/myImage.png" />
View Report
</asp:LinkButton>

From there, I’d probably just use some unobtrusive JavaScript to wire up the onclick event of the generated links to perform the “blur” functionality as specified above.

I’m sure a User Control could be created for even swifter and more concise ASP.NET implementation, but I haven’t taken the time to do that yet. If I do, I’ll be sure to share it here.

If you need some additional guidance on making stylish image buttons with anchor tags and CSS, I’d recommend reading the aforementioned article, How to Make Sexy Buttons with CSS, by Oscar Alexander.

Let me know if you’d like me to post the CSS/XHTML code for this example.

Comments and suggestions are always appreciated.

-Patrick

Preloading Images with JavaScript or CSS

Preloading Images on your Web Page with JavaScript or CSS

Note: This article is intended to be a tutorial for novice web developers and a refresher for web developers with more advanced skill sets.

Web Developers are always striving to create the best possible user experience. While it is often more convenient to deliver content with a minimal amount of images, the richest functionality is hardly ever the most convenient. And the richer the functionality, the heavier the payload that functionality requires. So after you’ve optimized your JavaScript, reduced the bit-depth of you GIF files, and trimmed the fat from your HTML code, what else can you do to facilitate a more fluid and expedient delivery of your content?

Preloading images can be a valuable technique for the developer to eliminate the subtle lag that separates a good page from a great page — if it is done thoughtfully and correctly. First, let’s examine a real world situation where preloaded images might come in handy.

Imagine you have an element on your page where you wish to employ a rollover effect. This is frequently used on form buttons or navigation bars as a way of illustrating a mouseover state or lack thereof. While the “Sliding Doors” technique is becoming the most frequently used approach for this type of effect, there may be situations where something else is needed. Let’s say that you have a photo gallery page. Each gallery item is displayed as a photo negative by default. When the user’s mouse enters the area of the image, you’d like the fully-developed photo to display. The problem should become somewhat evident if the photo files are of appreciable size. If the developed photo has not been preloaded, the user will have to wait for that process to occur when he/she moves the mouse over the photo negative. If the file is big enough (or the connection is slow enough), then this may have a substantial negative impact on the user’s experience.

So, any pre-emptive loading that you can effectively manage will generally translate into good results for your users.

Here, I will present two quick and easy methods for preloading images for your web pages.

Preloading Images with JavaScript

This technique has been around since forever, but, in case you haven’t needed it, or just haven’t used it in a while and could use a refresher, here’s how it works:

You can implement the script containing the preload statements using an external .js file or as inline javascript. The important thing is that you place the script in the HEAD tag so that the desired images load when the rest of the page loads. You’ll want something like the following:

function preloadImages() {
    if (document.images) {
        // Declare image variables
        var myImage1 = new Image();
        var myImage2 = new Image();
        ...
        // Assign image paths to variables
        // Make sure the paths are correct
        myImage1.src = "imagePath/fileName1.png";
        myImage2.src = "imagePath/fileName2.png";
        ...
    }
}

And that’s all there is to it.

You might also want to create a function that allows you to loop through a group of image URLs passed as an array. Here’s an example of that approach:

function preloadImages(imageURLs) {
    if(document.images) {
        for (index in imageURLs) {
            var img = new Image();
            img.src = imageURLs[index];
        }
    }
}

One noteworthy benefit of preloading images with Javascript is that all preloaded images will be cached according to the settings of the user’s browser just like any other image. Therefore, subsequent pages that use any of the same images may load faster.

Preloading Images with CSS

With the proliferation of AJAX and other JavaScript-driven UI frameworks (such as jQuery), I wish I could say that it’s safe to assume your end users are browsing with JavaScript enabled. Unfortunately, just as the old proverb warns us that we should never say “never,” software devleopers know that we should never say “always” either. So if you’re coding for a demographic that can’t be expected to take advantage of JavaScript but you still wish to preload images for some reason, you still have the option to do so. To do this, place an IMG tag that points to the image you want to preload and use CSS to hide the image. You can accomplish this using a style sheet or inline styles but a style sheet is generally considered best practice, so that’s what we’ll use for our example.

First, create a class in your style sheet that you will use to hide the images:

.hidden { display: none; }

An added bonus is that this class is quite ambiguous and can be reused for any other page elements you wish to hide.

Next, create a wrapper element for the preloaded images using the “hidden” class we just created. 
 
<div class="hidden">
</div>

Next, place an IMG tag in the body of the wrapper element we just created for each image you wish to preload, using markup like the following:

<img src="imagePath/fileName1.png" alt="Some Caption" width="1" height="1" />

Make sure you position these elements at the bottom of the page. Otherwise, the rest of the page may not load/display until the images are finished loading. I’ve added the 1×1 dimensions for each image tag in case the user’s browser doesn’t support CSS, in which case the bottom would be littered with a bunch of seemingly random images. Like the JavaScript method, images preloaded with this method will be cached and therefore cut down the load time of subsequent pages that use them.

So there you have it.

Unless you’re going for a Javascript-free environment, I’d advocate using the JavaScript method when possible . The CSS method is equally valid, but it results in a messier and less semantic HTML document structure.

I’d like to give credit and thanks to Jeff Star and his article A Way to Preload Images Without Javascript That is So Much Better for some inspiration on the CSS-only approach.

Your comments and feedback are greatly appreciated!

-Patrick