Forgotten CSS selectors

Anyone who has been using CSS for any length of time has probably been frustrated by the lack of selector support in Internet Explorer 6. There are quite a lot of cases where a CSS 2.1 selector will let you target elements in all other relevant browsers, but where you, if you want it to work in IE 6, have to add a class or id attribute to the HTML.

Well, the market share of IE 6 is now finally at a level where we as developers can say that a site “supporting” IE 6 does not necessarily mean “looking pixel perfect”. Fortunately more and more clients understand this as well. IE 7 has been out for well over three years and IE 9 is on the horizon, so I think it’s time to revive those CSS selectors that you never got to use just because IE 6 doesn’t understand them.

Here are brief explanations of some of the most useful “forgotten” CSS 2.1 selectors.

Child selectors

Child selectors target an element’s immediate children and consist of two or more selectors separated by a greater than sign, “>”.

This rule targets all strong elements that are immediate children of a p element:

p > strong {color:#a00;}

Adjacent sibling selectors

Adjacent sibling selectors consist of two simple selectors separated by a plus sign, “+”, and target elements that are the next sibling to the first element in the selector.

The following rule matches p elements that are immediately preceeded by an ul element:

ul + p {color:#a00;}

Attribute selectors

Attribute selectors, as the name reveals, match elements based on the presence or value of their attributes. There are four ways for an attribute selector to match, but I find two of them more useful than the others.

[att]

Matches elements that have an att attribute, regardless of its value. The following rule applies to all a elements that have a title attribute, regardless of which value it has:

a[title] {color:#a00;}

[att=val]

Matches elements that have an att attribute with a value of exactly “val”. In the following example, the selector matches all input elements that have a type attribute with the value “text”:

input[type=text] {color:#a00;}

:first-child

The :first-child pseudo-class matches an element that is the first child element of another element. The following rule applies to the first li element of each ordered list in the document:

ol li:first-child {color:#a00;}

:hover and :focus

Most people know about and use the :hover dynamic pseudo-class to control the way links appear when you place the mouse cursor over them. However, you can use this to style any element, not just links, which can provide useful visual cues in some situations. The following will give table rows a background colour when the user hovers the mouse cursor over them:

tr:hover {background:#eee;}

One very important thing to keep in mind is that you should assume that anything you use :hover for will only be visible to people who use a mouse, so only use it for non-critical stuff.

The :focus dynamic pseudo-class applies while elements like links and form controls have keyboard focus.

The following will apply to textarea elements that have keyboard focus:

textarea:focus {
	color:#000;
	background:#ffc;
}

Note: :focus does not work in IE 7.

Multiple class selectors

You can assign multiple class names to an element, and you can write selectors that target only elements that have several class names. The following rule will match p elements which have both “info” and “error” in their list of class names:

p.info.error {
	color:#900;
	font-weight:bold;
}

Be aware that IE 6 will only match the last class in the selector, so it will apply this rule to all p elements that have the class “error”. Keep this in mind when using multiple class selectors.

Cleaner markup through progressive enhancement

What these selectors offer us is cleaner HTML, since we can drop a lot of class names, and in some cases JavaScript, that were only necessary to achieve visual equivalence in IE 6. I am not saying that you should “drop support” for IE 6, just that it’s ok for some things to not look perfect in a web browser that is eight and a half years old. Besides, Do websites need to look exactly the same in every browser?

For a more comprehensive explanation of CSS selectors, see my article series on the topic:

Posted on February 4, 2010 in CSS