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.

The Many Faces of the Hyperlink

The World Wide Web is built on links. It thrives because links are everywhere. There are links to the various pages on individual sites. There are links from one site to another. There are links in e-mails to websites. There are links in PDFs and documents and presentations to Web pages. Chances are, you used a link to get to this article. Yet, when it comes to setting up a website, styling and consideration of links is often overlooked. Or worse, specific choices for links are made that end up hurting the usability and interaction of your website.

Link states and their selectors

A link isn’t just an element with one look. It has five different states that can be styled with CSS (and to some degree basic HTML, but you should be separating your styling from your content). Here are the different link states and their associated CSS selectors.

a:link
The link state is the basic state for a link. It’s the blue, underlined text default. A link that hasn’t had and isn’t currently having any action on it should look like this.
a:hover
The hover state is what happens when you move your mouse over a link. Typically, this involves a change in color or decoration. The mouse cursor also changes.
a:focus
Perhaps the most often overlooked state, the focus state is to keyboard navigability what the hover state is to mouse users. When a link is focused on using the keyboard, or after being clicked, it will use the definitions of this state to style it. Default styling generally puts a dotted outline around the element.

You can change the color, style and width of dotted outline (or remove it altogether, although that’s not recommended) in CSS with the outline property (ex. outline: #f00 solid thick;). In newer browsers, other elements can have outlines as well (allowing for double borders), although IE will only display an outline on links only.

a:active
The active state controls how the link appears right after being clicked (while the action is taking place, such as requesting a new page). This gives feedback to the user that their click was registered by the browser, and that something is happening, even if it isn’t readily apparent. The default for this is typically a red text color.
a:visited
If a user has viewed the destination page, the link is considered visited. This is important feedback for the user so that they can know which pages on your or external sites they’ve already seen, thus not needing to click on the link. Default styling of visited links usually colors the link an eggplant or dark purple color.

Each one of these selectors should have a different style. Why? It’s all about usability.

Usability

The Internet as we know it—that is, the one available to the public—was born right around 1992. That was 18 years ago. (Think about it, the majority of students in this years incoming college freshman class were born that same year.) In that time, visitors have come to expect certain things on the Web. For instance, what is the first thing that comes to mind when you see blue, underlined text? You said “a link,” didn’t you. Blue, underlined text has become synonymous with a hyperlink. People see it, instantly recognize “ooh, a link!”, then click on it if they think it looks interesting to them. They die a little inside if it doesn’t do anything. They rejoice if it takes them to another page. That is usability.

Usability: the ease with which a visitor can accomplish basic tasks on your site. Navigation is the most basic task on the web, after reading content.

If you’re only willing to put a minimum amount of consideration into link styling in your design or development, the best thing you can do is dont do anything to the browser defaults. Ok, so maybe those colors would be a little difficult to read on say, a black background, but at least users would understand that they’re links.

Users need to know four basic things:

  1. Specific text is actionable (that is, it is a link)
  2. They are hovering or focusing on it (taking action will do something and they’re clicking on what they intend to)
  3. Something is happening once they’ve clicked on it
  4. Whether they’ve already seen the destination

If your link looks like plain text, no one is going to try to click on it. They don’t have any cues to know that they can take action.

If your link doesn’t change when the visitor is hovering or focusing (via keyboard), they can’t be sure that when they click (or hit enter) something is going to happen. What if they do click but cause something else to happen? That’s bad usability. These two states (hover and focus) are perhaps the only two that I can consider ok to have the exact same styling. Both states indicate that pressing a button (on the mouse or keyboard) will activate the link. If you remove the default outline for the focus state, make sure to do something else that makes it very obvious to a keyboard user that the link is being focused on. Some browsers, like older versions of Opera don’t do anything with the focus state, and others, like IE6, end up meshing focus and active together, so having slight differences between hover and focus might be best for browsers that get confused.

If nothing immediately happens when a user clicks, they might think they missed the link or it is broken. They need feedback to know something is happening in the background, especially if it takes a noticeable amount of time to request the new page.

If they’ve seen a page on the site already, they might not want to visit it again right now. Or, if they’re clicking on various links to read after they’ve finished scanning your content, they might want to know if two links go to the same location. If your visited links look exactly the same as unvisited links, users have no indication of this. Give them some.

Consistency

I’m sure plenty of Web designers are cursing at me right now about stifling their creativity, saying “that color scheme looks like total dog-poo with my design.” And I totally understand that sentiment. You can style your links differently than the browser defaults. I do it. But if you do, at least keep it consistent.

If links on your website are say, bold orange text with no underline, people will probably pick up on the fact that bold orange text with no underline are the links on your site. But if you also use bold orange text for some other type of emphasis, people will be confused when they try to click and nothing happens. Or if another link is suddenly italic red text with an underline, they might think they’ve visited the link, or it’s not a link, or who knows what. It’s unlikely that they’ll click on it. Consistency is key. If you want your users to memorize a new paradigm, make sure you always use your new paradigm.

And please, for the sake of all things holy and unholy, don’t use blue, underlined text unless it is a link. (Or if you are a sadistic developer who takes pleasure in frustrating and confusing your users.)

Exceptions to the rule

There are always exceptions to the rule. The major one here has to do with in-site navigation. Obvious site navigation, like menus and footer links can be styled differently than normal hyperlinks. If users expected your navigation to be blue underlined text, the Internet would be a far more homogeneous place, and that would be boring. When you have obvious menus, your users are going to understand that those are links to other pages in your site. But when you have links within your content, they need to know immediately that they are looking at a link.

A side rule to this: don’t link to external sites from your site navigation without clear indication of what is happening. That is really jarring, and a good way to get people away from your website so that they don’t come back. Site nav links should almost never open in a new page, either.

What link styling strategies have you found work best for you?

Online Retailers: Help Your Customers Find Your Products

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

Aisle of products One of my favorite (only because it has the best, low-price selection) sources of quality fabrics has horrible UX on their store site. Horrible to the point that I’m only able to do rudimentary filtering because I understand the GET variables they use to display their catalog. In fact, I wrote a post to help non-developer users figure out how to filter the catalog by changing the URL. The fact that I had to do either of those things really bothers me as a front-end developer; your users should never have to resort to manipulating the URL in order to filter or find products.

If a user can’t easily figure out that you carry a certain product, you just lost a sale. Think about that and what it means to your business.

Say a customer walks into your brick-and-mortar store wanting a specific type of whatchamacallit with a budget of $5. They see that there is a whatchamacallit aisle, but it’s just overwhelming: you have have 200 different colors of that specific type of whatchamacallit. There are different sizes, weights, and patterns. The customer’s not too picky about some of the finer points, or maybe they are, but it doesn’t matter because they only have $5 that they want to spend. So, they want to quickly narrow it down to all whatchamacallits under $5. They could go down the aisle looking at every one, but it’s easier for them to find a store employee and ask, “can you show me the whatchamacallits that are under $5?”

Being a store that cares about making a sale, your employee says yes, helps the customer, maybe even upsells them, and the customer makes a purchase. Money in the bank for the store.

Now stop. Why should this interaction be any different in your online store? That’s right, it shouldn’t be. Sure, it’s a bit difficult to have a person there, so to speak (you could have a live chat function). But there are alternatives:

  • An obvious search box that accepts queries like “whatchamacallits under $5” and returns useful, intuitive results.
  • Obvious, intuitive filtering and sorting options for search results with obvious, intuitive controls.
  • Obvious, intuitive filtering and sorting options within categories with obvious, intuitive controls.
  • An obvious, intuitive way to change the number of items shown on a page.

Notice the similarities up there: obvious and intuitive. It’s not simply adequate to provide those controls; people need to be able to find them and use them easily—just like they’d need to be able to easily find a knowledgeable employee. Good online store software will have all of those things out of the box or your developer will set it up as a standard part of your store creation. All of these filters should persist until the user says to remove it, as well: if a user filters to blue whatchamacallits then applies a $5 filter, they should be shown blue, $5 whatchamacallits not just $5 ones in any color. Sounds like common sense, right? Too many online stores don’t seem to get it.

Now, back to the earlier example. What if your employee said to the customer, “no, find it yourself.” Maybe the customer would spend time looking, but more likely they’d realize that you don’t care about their patronage and they’d go somewhere else to find the whatchamacallit. You just lost the sale. You’d probably fire an employee that did that consistently.

That’s exactly what’s happening at the fabric store. And many other online stores with outdated store software that has no filtering. There’s no provided way to easily narrow the products down to a specific one you’re searching for. There’s a search function, but it’s not that great, and there’s no way to narrow down the results. There’s absolutely no way to sort of filter the category item listings at all. They need to fire their store software.

Keep in mind that simple categorization is not sufficient criteria browsing or searching. Just because I want a whatchamacallit doesn’t mean I’m interested any whatchamacallit you carry. Shoppers, whether they’re just browsing or are looking for a very specific item, are more likely to buy from you if they can find what they are looking for. If they can’t find it, they can’t buy it. If they’re browsing a sales listing hoping to find something they think they need, you’ll have more success on a conversion if they can narrow down that sales list to items they are interested in. Sure, they can start at the top—viewing everything—but maybe they see a coolthing that intrigues them, but it’s not the perfect coolthing they want to buy. If they can easily narrow that listing to all coolthings, your ability to sell them something just increased. They know you carry the type of item, and are easily able to drill down to all items of that type. If they can’t, then maybe they keep looking, or maybe they get bored after going through another 2 pages with no more coolthings because all the other coolthings are 12 pages into the sales. A bored visitor leaves, and so does their money.

What do you expect from online shopping user interfaces? What makes you go to another store? Stay at the current store? Feel free to share good or bad experiences and examples in the comments.

Trigger AJAX Error Event

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

When I was new to working with AJAX functions—especially in the realm of form submission—one hurdle I often encountered was how to handle processing errors in my back-end script and give meaningful feedback to my users. I didn’t understand how to designate a response as an error instead of successful processing. Early on, I sometimes employed a dirty hack of prepending any error with the string ERROR: and then adding in some quick checking to see if that substring existed in my response text. While that may get the job done, it’s not good form. It causes convoluted code usage, thumbs its nose at existing error handling functionality and makes future maintenance a headache. But there is a better way by simply utilizing your processing language’s inherent header and error handling functionality.

N.B. From a JavaScript standpoint, I’m showing code based on the jQuery library, because I use it on a regular basis. The concept of triggering the XMLHttpRequest object error handling with proper headings is applicable to any type of JavaScript coding. Likewise, my server-side processing examples in this article are coded in PHP, but that is not the only applicable language. You can produce similar results with other languages as well, so long as that language allows you to send header information. If you’re willing to translate my examples into another language or non-libraried JavaScript, please do so in the comments or e-mail me (rae.arnold@gmail.com), and I’ll add it into this article (and give you credit, of course).

The information in this article refers to AJAX requests with return dataTypes of html or text. JSON and XML dataTypes are for another day.

The client side of things

Let’s say we’re working with a bare-bones comment form: your users add a name, e-mail address and their comment. Three fields, all required, easy-peasy. For the purposes of this article, we’re going to ignore all of the validation you would want to do on the form and focus solely on the process of sending it via AJAX to your PHP processing script. The resulting AJAX call with jQuery might look something like:

//[warning: most of this is pseudo-code, not code you can copy+paste and expect to immediately work]
$.ajax({
    type: "get",
    url: "/processing/process_comment.php",
    data: $("#commentForm").serialize(),
    dataType: "html",
    async: true,
    beforeSend: function(obj) {
        //give user feedback that something is happening
        showProcessing();
    },
    success: function(msg) {
        //add a success notice
        showNotice("success",msg);
        clearForm();
    },
    error: function(obj,text,error) {
       //show error
       showNotice("error",obj.responseText);
    },
    complete: function(obj,text) {
        //remove whatever user feedback was shown in beforeSend
        removeProcessing();
    }
});

Essentially, the above JS expects the server-side processing script to return a message to show the user. We’ll set up such a script next.

The server side of things

Processing our simple comment form is close to trivial. We’d want to do some basic validation, make sure the submitter hasn’t been blacklisted for spamming or other reasons (in this example based on IP address), and then add the comment to a DB. The interesting part, however is how to tell the server that an error occurred during the processing and have that error propagate back to the AJAX properly. This is where the header and exit functions come in handy. Look at this example:

<?php //[warning: the "processing" is pseduo-code functions, however the error throwing parts are valid]
    // perform validation
    if (validValues($_GET)) {
        if (blacklisted()) {
            header('HTTP/1.1 403 Forbidden');
            exit("Uh, hi. Your IP address has been blacklisted for too many spammy attempts. Back away from the keyboard slowly. And go away.");
        }
        if (addComment($_GET)) {
            // We have success!
            print("Your comment has been successfully added.");
            exit(0);
        }
        // if the code reaches this point, something went wrong with saving the comment to the db, so we should show an error
        header('HTTP/1.1 500 Internal Server Error');
        exit("Something went wrong when we tried to save your comment. Please try again later. Sorry for any inconvenience");
    } else {
        header('HTTP/1.1 400 Bad Request');
        exit("This is a message about your invalid fields. Please correct before resubmitting.");
    }
?>

In PHP, the header function allows you to send headers to the client. In the syntax used above, it is allowing us to specify error status. For more info on the header function, head to the PHP manual on header. exit is a handy construct that ends script execution while allowing you to print an error. Upon successful completion of the processing, we make sure to call exit(0), which signifies successful completion of the script. Any non-0 value indicates that an error occurred. Learn more at the PHP manual on exit. For errors, you can also use the die construct, which is equivalent to exit.

Putting it all together: View a Demo

Let’s get advanced

The above examples for the error function are pretty simple, but you can create very elegant error handling solutions with it by utilizing other properties of the XMLHttpRequest object. One possibility is to take unique actions based on status code returned. By using the status property of the object, you can customize your error handling based on the status returned. For instance, this error function script would alert a user to modify form information if needed, but completely remove the form if they found the user is a blacklisted IP (using the same server-side script from above).


    error: function(obj,text,error) {
        self.showNotice("error",obj.responseText);
        if (obj.status == "403") {
            self.remove();
        }
    }

Have you utilized this method in your AJAX programming before? Let us know how it worked for you.