come on my selector pt2/the future

February 01, 2008 / 12:27

An update was made to the article, separating pseudo-classes and pseudo-elements in two separated chapters

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.

blog archive

All my articles are neatly filed inside the archive. Search and filter your way to the article you like:

contact me

If you want to leave me a quick message or you have any questions, drop me a note.

Comment author
7 comments in total
February 05, 2008 14:48

I've read both these two articles, good read. But in this article is somewhat unclear. :after is a pseudo-element so it isn't correct to place it under pseudo-classes. You do mention that :after generates a virtual element, that is correct but it still not a pseudo-class. You could have written about what is the difference between pseudo-classes and pseudo-elements. In CSS 3 pseudo-elements is marked by double colons, eg. ::after, so in that way they are easier to tell apart from the pseudo-classes. http://www.w3.org/TR/css3-selectors/#pseudo-elements

February 05, 2008 16:04

One thing you can do is use a javascript file fed to IE6 only using conditional comments. Especially jQuery with its $ selector that supports these advanced selectors (as well as Xpath) can used to patch these styles for IE6.

February 05, 2008 17:01

Nils: I stand corrected! Fixed the article and split the pseudo-selector chapter in two separate chapters. Thanks a lot.

Erwin: I know there are javascript fixes out there, problem is that those without javascript will get a terrible layout. If possible, I'd like to avoid that as much as possible. On the other hand, if you're working for a closed environment, those libraries can offer a great solution.

Michelangelo
February 05, 2008 21:48

One important use for some of these selectors (once they are supported) is that our CSS and HTML will become simpler and lose some weight. We won't need nearly as many classes because we will target specific elements and attributes directly.

February 06, 2008 09:56

I don't think they will have a great effect on file sizes to be honest.

There's more to classes and ids than its function as css hooks. I can whine all I want about the details of some Microformats, but the general idea behind it is great, so in that sense, the extra selectors won't have much effect on the use of classes and ids (just a couple of first/last classes maybe).

More importantly, simply working on html elements and relying on selectors like >, ~ and + can put a strain on flexibility. You could argue that you can add extra classes when needed, but in my opinion it's better to have as little html changes as possible after a site was implemented. The more you can do with css only, the better.

February 06, 2008 12:48

You mentioned CSS3 in your article twice as if to suggest that these selectors are CSS3 but all of them (except for ~) are part of CSS2.

It might be useful for readers to know that the

  • > is called the child selector
  • + is called the adjacent sibling selector
  • ~ is called the general sibling Selector

Also, although [id="myDiv"] and #myDiv will match the same element, they're not equivalent because they have different levels of specificity.

February 06, 2008 13:35

I care little for the actual numbering of css so if somehow I implied that these are uniquely css3 selectors I apologize. This wasn't my intension.

Furthermore, you're right about the specificity difference between the attribute selector and id selector, but I will leave the explanation (and discussion) of css specificity for another article. I simply tried to lay out the different means of targeting html in these two articles.

* required fields

Leave your data
Leave a comment