Looking for the previous guiStuff?

It's still here, the content didn't go anywhere. You may want to check out this new guiStuff though -- It's rather informative.

References/Tutorials:


Intro Documents:


guiStuff:






::Stuff for the multi-spec coder;

Coding, formats, standards, and other practical things.

 Home  //  CSS Articles  //  CSS Selectors: Part 2 

<!-- CSS Articles

CSS Selectors: Part 2

In Part 1 of CSS Selectors I talked about Type Selectors, Descendant Selectors, Class Selectors, ID Selectors, and the Universal Selector. In this document, we'll go over styling links, which is made up of two parts (called Link Pseudo-Classes, and Dynamic Link Pseudo-Classes), and then styling using the less-supported (in terms of browsers) types of Selectors. As in the first document, perhaps more so, understanding the the Document Tree is required to understand how to implement the CSS Selectors described here.

The Link Pseudo-Classes

Unlike most Pseudo-Classes, the Link Pseudo-Classes have been implemented quite well across the great majority of browsers currently in use. This is mainly because browsers have already had to deal with the dynamic nature of links in some manner, and these pseudo-classes date back to the early releases of CSS implementations. CSS doesn't "care" that we use the A element along with the href attribute to create hyperlinks. As far as it's concerned, the next version of XHTML may allow other element types to have the href attribute (and by the looks of it, that might be the case), and so the Link Pseudo-Classes of :link and :visited can be applied to anything. The difference between the two is obvious from their names:
  • :link - applies to links that have not yet been visited.
  • :visited - applies to links that have already been visited by the browser.
Of course, if you want them to mean anything, you'll want to apply them to valid HTML links, ie -- A elements. The basic application is so:

a:link { color: #800; } a:visited { color: #B00; }

This will match all A elements within a document, and override the browser's default color settings for unvisited, and visited links. You will likely wish to create more specific selectors, which style links in specific areas of the document. When doing so, you'll need to keep in mind that the Pseudo-Class syntax is somewhat different than what you may be expecting. Take a look at the following rule:

#space a.zone:link { color: #800; }

As you can see, the Pseudo-Class does not attach itself to the type selector, but is rather appended at the end of the selector definition. This particular rule is looking for an A element that was styled by the zone class, and is a descendant of an element with the space ID.



The Dynamic Link Pseudo-Classes

Like the Link Pseudo-Classes, the Dynamic Link Pseudo-Classes have broad browser support for most CSS properties. The Dynamic Link Pseudo-Classes are the :hover and :active. They really are dynamic in the sense that they make a change to the document without it technically having been reloaded. This means that when one of these becomes activated, the renderer of the document (here it really must be a browser, since we're talking about hyperlinks) must re-render the document to comply with the new properties that have been assigned to the elements who've been styled using these Dynamic Link Pseudo-Classes. Here are their respective functions:
  • :hover - is activated when a pointing device (commonly the mouse-cursor, but remember that touch-screens technically don't call it that) overlaps the area of the element ("hovers", or mouse-overs it), but does not yet trigger the event related to the element (commonly clicking the link).
  • :active - is activated when the user triggers the event related to the element. This refers to the time between the user clicks down on their mouse button and the time they release it. This may also refer to other events in the future.
When implementing these Dynamic Link Pseudo-Classes, you need to consider the assignment-order. When you're creating CSS Style Rules for your links, you'll normally want to create Pseudo-Classes for :link, :visited, :hover, and :active. You need to create the rules for :link and :visited first, followed by :hover, and then :active last. This is because of the overlapping nature of these selectors, and how they're implemented in practice. You can, however, style both :link and :visited together, and then :hover and :active together (using the normal comma ',' separation).

Here are a couple of implementation examples:

a:link { color: #800; text-decoration: none; } a:visited { color: #B00; text-decoration: none; } a:hover { text-decoration: underline; } a:active { text-decoration: underline; }

The above example removes the usual underlines from links, and resets their colors. When they are 'hovered' over, or 'activated', they become underlined.

Here's another example:

a:link, a:visited { color: #800; text-decoration: none; font-weight:bold; } a:hover, a:active { text-decoration: underline; }

This example groups the :link and :visited into one rule, and the :hover and :active into another. You can technically group them all into one rule, but this is not recommended, even though it would theoretically solve the overlapping properties issue. This time, visited links would appear just like unvisited links, since both were assigned the same color property. Links would also appear bold, and again, have no underlines. When hovered, or activated, they'll display an underline.

A common mistake that is made when styling links is giving the :hover Pseudo-Class a font-weight of bold, when normal links have a font-weight of normal. While this works, and won't always "break" the browser, it will change the width of the rendering box of links when they are hovered over, which can lead to a domino-effect that would require the page to undergo a significant re-render, instead of a local one. This should really be avoided, since it may lead to not only very upset users when the page reacts slowly when they move the cursor around, but it may also lead to a resonance effect where the link switches back and forth from the :hover style to the :link style, at a very high pace. At best, this is highly annoying. At worst, this will crash the browser.

The :focus Dynamic Pseudo-Class

The last Dynamic Pseudo-Class (note that I didn't say Dynamic Link Pseudo-Classes) is the :focus Pseudo Class. Unlike the classes mentioned so far, this one has far from broad browser support, and even weirder "browser-interpretations". The intention is simple: Apply this rule when an element gains focus. In an interactive environment, like a browser, many elements can gain focus. Most commonly (and inherently) form elements/fields. However, remember that form fields are rendered differently by different browsers/platforms, which in turn have different properties, many of which are proprietary. Earlier versions of HTML did not account for these "conformance battles", and didn't take into account that future platforms will be fighting over branding. These earlier versions did not include pixel-for-pixel (or vector-for-vector) detail on how each form field should be rendered, and left it up to the implementors of the spec to decide for themselves how to deal with this. And they did. At any rate, I could detail how to implement this selector and how it would manifest itself on various platforms, but considering the current browser/platform landscape, it would be best for me to advise you to simply avoid it altogether. You can experiment with it using different browsers and assigning it to different elements, but for the most part, there isn't much practical use for it at this point in time.

Murky Waters Ahead...

So far, we've gone over selectors which you could use safely and know that if your code validates, then you just need to worry about the weird browser quirks that pop up when you're implementing them. Now, however, we're going into territories in which some browsers won't have the slightest idea what you're talking about. When I say "Some Browsers", I'm mainly referring to Internet Explorer 6. Several of these selectors would have been wonderful to have as part of our CSS toolkit, but considering the amount of people who still use Internet Explorer 6, we're only able to use them within contained environments where we know how our data is accessed, and/or condition the loading of certain Style Sheets using scripts, which usually, in the end, leaves you with more code than just working around the problem using a different CSS-only approach.
So why keep reading? Well first of all, CSS is cool, and if you've liked the story so far, you may want to stick around for the rest of the plot. Second, I'll be discussing selector implementations along the way which will apply to other types of selectors, which you can use with the safe selectors you've been reading about so far. Third: it's free...

Let the march begin.

Child Selector

We'll start with a selector that, if it were just included in IE6, would completely change the way people design and manage Style Sheets. What this selector does is simple: It selects an element type which is a direct descendant (a child element) of another specified element. This is somewhat similar to the Descendant Type Selector, but this time, it will only match the specified tag if it's a direct descendant (or, as mentioned, a child). The difference was discussed in the Document Tree article.

Here's how this is implemented:

p > em {color: #700;}

What the above rule means is that whenever an EM element is a child of a P element, it will be assigned the color property value of #700. If an EM element happens to be a child of a STRONG element, which in turn is a child of a P element, then it would not be matched by this rule, because that would make that particular EM element a descendant of the P element, but not a child, or a Direct Descendant.

But wait, you should hear what else you're missing out on here. Remember the Universal Selector? That's the one that matches everything, when used on its own. Well, selector types, like this child selector, can be mixed with other types like we've seen in Classes in Part 1. Can you guess what the following rule does:

.something > * {border-bottom: #888 solid 1px;}

This is again like navigating the document tree. You have to convert the syntax into a definition: This rule is looking for any Child of any element that was styled by the .something class. Mind the use of the term any Child -- This is due to the Universal Selector that followed the Child Selector (> *). Another way of saying it is that any Direct Descendant of an element styled by the .something class will be matched by this rule.

This last example is a muscle-flex for the browser's CSS Standard compliance, so while Firefox 2.0 and Opera 9+ "agree" about the result, Internet Explorer 7 comes up with some different interpretations. Internet Explorer 7 should support the Child Selector, but stand-alone support doesn't mean you can create any hybrid with the selector and throw it at the browser (well, not with IE7, the other browsers don't seem to have too much of a problem with it). What this means is, well, if most internet users use some version of Internet Explorer to browse the web, even the upgrade to IE7 won't let CSS designers go wild with this selector.

Adjacent Sibling Selector

Another sense-making, Markup-saving selector that we'll have to play with offline for the moment is the Adjacent Sibling Selector. Unlike the other relationship-targeting selectors we've seen so far, which all drill down the document free, this one goes sideways. It selects an element that follows another in the document tree, if both share the same parent. I'll first give an example:

h3 + em {text-decoration: underline;}

In the rule above, the subject of the rule is the EM element. The rule means that any EM element that follows an H3 element, which is also its sibling, will have the text-decoration property value of underline assigned to it. So what do we have to gain by "selecting sideways"? Well, think of a page in which the author knows that the H3 heading will always be followed by a date. The author doesn't want to place the date within the H3 element, because, say, he's styled that element with certain border properties. But he knows that the H3 heading will need some form of date to follow it, so he assigns the EM element to follow the H3 element. Now that's not to say that the H3 heading will always be followed by an EM element, or that the EM element will only be used for this purpose, however, when the two elements do appear one right after the other, then this this style will be triggered, and match the EM element in question.

But let's say that's not specific enough. You might be thinking "the EM element might appear after an H3 heading by mistake". Let's make it more specific then:

div > h4 + em {text-decoration:underline;}

How's that for specificity?
Yes, this rule combines two 'unsupported' selectors, in the "in for a pennie, in for a pound" spirit. The rule goes looking for an EM, which follows an H4 sibling, which is a child of a DIV. You won't get many false positives there. Surprisingly, IE7 seems to match this one well, at least with the tests that I've run. Firefox 2.0 and Opera 9+ have no problems with much more involved expressions.

Attribute Selectors

Attribute Selectors match elements by their, you guessed it, attributes. HTML/XHTML elements have many common and specific attributes to match (src, title, width, alt, etc.). You have four ways to select attributes. I'll go through them one by one:

The first way you can select an attribute is to check if it exists:

img[alt] { border: #00D solid 2px; }

This rule will look for all images (IMG elements) on the document that have the alt attribute, and assign the border property value of 2px to it. The rule doesn't care what value was assigned to the alt property, it just looks to see if the element has one.


The second way to select an attribute is to check both if the attribute exists, and if its value matches a specific string:

a[href="http://www.fsf.org/"] { font-weight: bold; }

The above rule will match A elements who's href attribute value match exactly the "http://www.fsf.org/" text string.


The third way to select an attribute value is using a space-separated list of words. This one's a bit trickier that the previous two. This time, you're looking into the attribute's value, and expecting to find a row of words, separated by spaces. Here's an example:

img[alt~="bordered"] { border: #00D solid 2px; }

This rule will match images with alt attributes that contain the text string "bordered", within a space-separated list of words. For example:

<img src="example.png" alt="light bordered" />

This brings up all sorts of interesting uses. You can have the alt of images serve as a second class attribute, and nothing says you can't match the class attribute itself! (which, by the way, would have enabled you to have two separate style sheets operating on the same class attribute value assignments...)

The fourth and last way to select attributes is just like the third, except you're looking for a list of words separated by hyphens (-). To do this, you'd use this syntax: img[alt|="bordered"]. Apart from that, it's the same as the other list-matching method.

Support for Attribute Selectors is about what you'd expect by now. IE7 has its ups and downs, while Firefox and Opera keep up well. List matching is trickier for the browsers to get right than one-to-one matching, since there are more things that may clash along the way.

How many do you need??

A common question that crops up among new designers implementing CSS is "why would you possibly need that many ways to say 'THIS!'?".
The reason is simple: by creating more specific and involved CSS Style Rules, with thought-out Selector design, you can reduce your HTML/XHTML markup quite a bit. And remember, it's the markup that's going to take the bulk of the bandwidth/storage, not the CSS. Also, it makes it easier to update and maintain your HTML, and it makes it easier for search engines to find content on your pages and list them in their databases (directly effecting your Search Engine Optimization, just as an added bonus).
Well crafted pages have relatively few classes and/or IDs, and take advantage of relative units and CSS inheritance to reduce the amount of markup, and to enable the user to easily change font-sizes while keeping the structure of the page intact. That's not to say that you'll get everything right the first try (I rarely do...), but with some practice, and peeping into other people's source, it won't take you long to get the hang of it.

Merry Experimenting!



Return to the CSS Articles section, or go the to Main page.





Looking for the old guiStuff?

It's still here, the old content didn't go anywhere.