Pseudo-class Deception

Those who are new to using pseudo-classes in their CSS may experience more than a little confusion, and I hope that I can relieve a few headaches. For those who use them frequently, I hope they find a few interesting observations ahead.

I attribute much of the confusion surrounding pseudo-classes to the misunderstanding of the prefix 'pseudo'. As with pseudoscience, the prefix does not indicate a partial relationship ('quasi' would be more suitable) but a false one. Why the CSS specification should include items seemingly designed to confound the user is anyone's guess but, just as pseudoscience should never be likened to real science, pseudo-classes have nothing in common with classes.

Classes and pseudo-classes

As the name suggests, classes are a way to group elements (to classify them) together. Users create their own classes (and use their own naming conventions) to organise the styling of their elements, before adding them as attributes like so:


<div class="my-block-class"></div>

Defining the purpose of pseudo-classes is a little more difficult, but it is clear that pseudo-classes do not have the same organisational capacity, especially since coders cannot create or name their own.

Essentially, pseudo-classes are a means to access elements in the DOM more specifically. Whether you are using li:last-child to specify only the last item in a list or a:hover to access the 'hover state' of anchors, you enjoy increased granular control of your document's appearance without relying on a classification system or having to edit the markup itself.

Furthermore, pseudo-classes do not depend on classes to work. Both of the following uses of :hover are legitimate:


.link-class:hover {
   color:#ff0;
}

a:hover {
   color:#ff0;
}

The :active pseudo-class

Of all the different pseudo-classes available to the coder (many more since CSS3 has become more widely supported) the :active pseudo-class is perhaps the most perplexing and - unlike its popular stable mate :hover - it is rarely called upon to affect appearance any differently than browser defaults dictate.

The :active pseudo-class is the last of the pseudo-classes associated with anchors (hyperlinks), preceded by :link, :visited and :hover. You may (as I first did) expect the :active pseudo-class to relate to links with an href attribute identical to the current page. That is, you might expect it to help indicate the user's 'active' location. This would indeed be very handy and the misconception is given credence by frameworks such as Drupal which add an 'active' class (that's right - class, not pseudo-class) to the menu item referring to the page/URL that you are looking at.


a:visited {
/* This tells you where you've been */
}

a:active {
/* so why doesn't this tell you where you _are_? */
}

a.active {
/* This could help, though. */
}

In reality, the :active pseudo-class activates on links that are currently being pressed. Like :hover, it adds tactility and, therefore, usability to a page's calls to action and can be thought of as the depressed state of a button. It can indeed be used to enhance a button-like link style.

Away with defaults

The standard in most browsers is to style links in their active state with a dotted outline. Not all designers like this, however, because it marks a box around their links and not all link designs are box-shaped. You can easily remove this effect with the following:


a:active {
   outline:none;
}

It's not a good idea to forego styling the active state altogether, though. Not only does it offer the elusive 'tactility' that we discussed, but it is also important for accessibility. You see, GOOD browsers employ another pseudo-class (:focus) to help users traverse the page using the TAB key. The :focus pseudo highlights the link that has been 'tabbed onto' indicating that it can be used (via the ENTER key). Versions of Internet Explorer do not support :focus but misuse :active for the same end result. For this reason, all elements deserving of :focus should also carry :active.


a:focus, a:active, input:focus, input:active {
   outline:1px solid #999;
}

Putting it together

Forgetting :visited for now (which I rarely use), the anchor-related pseudo-classes all describe states of interaction and, since they must happen in order, I reckon good anchor styling should be about describing this chain of events as a whole.

I have attempted this on HeydonWorks by using increasingly pronounced styling from each state to the next, like so. The intention is to show levels of commitment. 'Commitment' isn't necessarily the best metaphor, but it works for me!


a:link {
   border-bottom:1px dotted; 
/* A feint line indicates availablility only; zero commitment */
}

a:hover {
   border-bottom:1px dashed;
/* Stronger line shows willingness to commit */
}

a:active {
   border-bottom:2px solid;
/* Strong, thick line; a commitment between the user and link has been made */
}