come on my selector pt2

Building on my previous article on basic css selectors, I'll continue by listing the css selectors that can already be used today, but are not yet supported in all browsers. A final article will close this mini series on css selectors by focusing on a very nasty IE6 bug.

In the previous article, I listed all css selectors that could be used without worrying about browser support. In this article, I will expand that list with the selectors that can already be used in some browsers, but fail to work cross-browser.

If you want a complete overview of all css3 selectors, you can check the w3c css3 selectors table on their site.

the > combinator

ul>li { *properties* }

If there's any combinator I really miss in my everyday css work, it is this one. The > combinator targets the specified elements exactly 1 level below the source level. In the example above, the selector will target all li elements that are nested right below the ul element. This comes in handy when elements with a rigid structure are nested inside a document.

IE6 is the only browser not supporting this selector, but sadly the absence of a good workaround makes this a serious loss.

the + combinator

h2+p { *properties* }

The + combinator targets an element on the same level, directly following the source target. In this example, it will target every p tag directly preceded by an h2 tag. This has some use in typography, but overall the use of this combinator seems quite limited to me (as it puts a serious strain on the flexibility of the html code).

Again, the major culprit is IE6 here, all other browsers support the combinator flawlessly.

the ~ combinator

p~p { *properties* }

This combinator is similar to the + combinator, but selects all elements on the same level, following the source target. It's somewhat more flexible compared to the + combinator, but I still haven't found too many good examples where the ~ combinator could be used to full effect. In the example above, all p tags that are preceded by a p tag on the same level will be targeted.

I know I'm becoming repetitive, but again, it's IE6 that's not supporting the ~ combinator. Bad bad browser.

the attribute selector

input[type=text] { *properties* }

What not many seem to know is that the class and id selectors are simply shorthands for specific attribute selectors. For example, the .nav selector can also be written as ul[class=nav]. Important difference is that an attribute selector has to be defined on an html tag, while the class selector can be used separately from html tags.

In the above example, I've opted to use the input tag, as it's the best use for the attribute selector I've found so far. Another interesting case is the use of the lang attribute, which can be styled according to language specific needs (fe changing the width of an element when the translated text needs more space).

The selector isn't simply limited to the "=" operator, but can also accept *=, $=, ^=, |= and ~= operators. Mind that cross-browser support for all these operators is pretty shaky at best.

the pseudo-classes

div:hover { *properties* }

Pseudo-classes are a varied bunch. A pseudo-class always starts with a : followed by the class itself, and can be attached to any selector. Pseudo-classes don't target elements themselves, but refer to the context or the behavior of an element. In very specific cases they can be made to work cross-browser (the :active class on the a tag for example) but most of the pseudo-classes have limited to no cross-browser support.

The example above will be triggered whenever a user hovers above a div element. You could for example change the background of an element to give an extra visual cue for people browsing your website.

the pseudo-elements

div::after { *properties* }

Pseudo-elements resemble pseudo-classes a lot. They share the same syntax although this will change for pseudo-elements introduced in css3. The single : will be replaced by a double ::, clearing up some confusion between both selector types. Pseudo-elements create virtual additions to the dom tree which do not exist in the html code. By doing this, specific parts of an element can be targeted, or completely new elements can be inserted before or after the source element.

In the example above, a virtual structural element is added after all divs. In this virtual element, content can be inserted which can then be styled. This virtual element will not show up in the dom however.

The use of both pseudo-classes and pseudo-elements can be quite complex and more specific details will be left for further articles, but they are a powerful bunch.

complex css rules

.box>*:first-child~* { *properties* }

With all the knowledge of css selectors, statements like these should pose no problem at all. Consider this a little exercise and try to figure out what it does.

so what, we can't use them anyway

You might be wondering why you should bother with all this. The selectors above can't be used to work cross-browser, so unless you are making a site for a specific environment (or you don't care about IE6 anymore), the practical use of all these selectors is terribly limited. For some selectors there are browser workarounds to mimic their behavior, but implementing those means extra production time and more trouble maintaining the stylesheet.

Still, I think it's important to start investigating (and broadcasting) possible uses of these selectors. IE6 is slowly disappearing from the web and when it finally disappears completely, it's already too late to start investigating those advanced css techniques. As a conscious web developer, it's good to be ahead of your time, at least you will be ready when the time comes.

In future articles, I will discuss some practical uses of the above selectors (and really, some of these selectors will have a great impact on well-implemented css, which will make css layouting all the more powerful). In the meantime, I'll gladly listen to all suggestions about using the above selectors to improve the css we are writing today.

If you want to check how your favorite browser handles css3 selectors, you can use this helpful css3 selectors test page.