the space combinator/nothing important
Combinators are an overlooked part of css development. Most juniors don't even know they are making use of them, others are unaware of their full potential and let's face it, even most professionals don't really know about the ins and outs of css combinators. It's all connected to that little piece of nothingness in between class names, so let's start by taking a good look at the space (descendant) combinator.
I assume that most people reading this will be well aware of the functionality of the space combinator, feel free to skip the first section which is a simple introduction of what it is supposed to do.
space combinator
.class1.class2 {...}
.class1 .class2 {...}
Spacing is pretty free-form in css. The most important exceptions are the space characters used between the first and last element of your css selector. Remembering the old days, it took me a while to figure out that the space character was more than just a way to increase readability. It wasn't until I started putting multiple classes on a single html element that I found out about the difference in both statements above. The W3C calls the space a descendant combinator, their exact definition can be seen below.
quote A descendant combinator is whitespace that separates two sequences of simple selectors. A selector "A B" represents B that is an arbitrary descendant of some ancestor A. unquote
So basically, the simple selector after the whitespace could appear anywhere in the DOM below the simple selector in front of the whitespace for the full selector to match. It's a pretty vague relationship that doesn't cut it in modern web design, still we're stuck with this single combinator to do most of the work today. There's a very good reason for that.
ie6 and combinators
It's time to point fingers to that certain browser once again. IE6 is notoriously bad when it comes to combinator support. Apart from the descendant combinator there is not much that works. Now, it's not the first time that IE6 is being a bitch about css support, the thing is that there are no good workarounds to make combinators work like they should in IE6. It will basically fail to recognize your selector and ignore your well-written css.
/* child combinator */
.class1>.class2 {...}
/* crappy fix */
.class1 * {margin:1em;}
.class1 * * {margin:0;}
There are some JavaScript solutions to add support, just as there will probably be a .htc hack floating around, but none of these give any solid results. Attempts to fix it in css usually end up in tears, as the example above illustrates. The child combinator links selectors which are direct children (no DOM levels in between). The fix works in certain circumstances, but the last statement might overrule some elements far below .class1 which did receive a margin of their own. It's really no way to start writing css.
education
Most people learn css on their own. They check other people's code and try to understand what is happening. Some buy books, but even those can be quite vague when it comes to the different combinators available. Fact is that combinators besides the descendant combinator are hardly ever used in real-life web design. There aren't too many css files out there that make full use of the available combinators, even those sites that won't support IE6 no more.
That why it is extremely important to make junior css developers aware of the possibilities out there. When left to themselves, chances are that they will take a long time to find out about these crucial tools. Of course it's much easier to just tell them about what the space character means and how they can apply it, but if you leave it at that they will face a serious hurdle trying to overcome their combinator handicap later on.
the future
With all the blame put on IE6, you might expect that we will see some serious improvement once that browser is finally put to rest. That's why I would advise you to go out and try to make maximum use of these other combinators available. It won't take you too long to start noticing that there are still plenty of issues left to be discussed. Here's a short list of things I noticed so far:
- Readabiltiy greatly decreases when using ">", "~" or "+".
- The child combinator is rendered useless when inserting an extra wrapping element in your html code.
- There's no obvious difference between
.class>*~*and.class>*+*. - Setting up a basic parent/child grid (
.parent>* {margin:1em;}) can be quite tricky.
Current day web development asks of us to design elements as separate components. Nested elements shouldn't necessarily be influenced and context should decide for itself how to handle these components. With all the extra combinators currently available I still haven't found a way to achieve these requirements. Furthermore, I've found some very practical issues when applying the current combinators as is. This is not very hopeful.
conclusion
The combinator remains one of the weak point of css. Sadly it doesn't receive too much attention from us web developers either. We as an industry are screaming for fancy graphical support, but with all that we still can't write solid, robust css code which is portable, reusable and flexible all at once. We often blame IE6, but those who tried using unsupported IE6 combinators might have noticed already that they won't really suffice either.

Thanks a bunch for clarifying. Now I'm wondering about those other combinators. Are you going to explain to us what they mean? I feel as if it'd benefitted the article a great deal if you'd expanded on those as well.
If you want, you can check the following articles for that:
http://www.onderhond.com/blog/onderhond/css-selectors-pt1
http://www.onderhond.com/blog/onderhond/css-selectors-pt2
I personally find the current combinators, as well as attribute selectors, perfectly reasonable in modern browsers; even IE7 tends to play reasonably well to some extent.
Attribute selectors really are the power horse that allows me to code layouts with virtually no classes or ID for styling, and with the main JavaScript libraries providing amazing selector support as standard, you don't even need to add any for JS hooks. This does result in more convoluted selectors in my CSS files, but as far as I'm concerned, the HTML is more important than the CSS when it comes to looking pretty and clean.
With the addition to CSS3 of
nth-childselectors, and loads more verbose pseudo selectors, I think it's only going to get better from here. The only think I wish for is a more reliable styling of form elements within browsers, and for more CSS3 support to make it mainstream ASAP ...Nathan: writing css like that is okay if you need to make a site, put it online and leave it like that for the next couple of years. In all other situations, I would go for a greater separation of html and css.
Clean html is nice but not at the cost of inflexibility. You're of course free to do as you like, but I'd be striving a bit more to a html/css setup that allows for maximum flexibility. Adding elements to your html should have minimal impact on the css, at least, in my opinion.
A nice javascript library to help internet explorer 6 is http://code.google.com/p/ie7-js : it fixes many internet explorer bugs and aims to make internet explore 5.5 and 6 compatible with internet explorer 7. It includes versions to get compatibilty with internet exploer 8 and 9 too!
@Neils I agree to a certain extent. Yes, using nth-child selectors places the burden of order dependence back on HTML, but the point is that the power is there if you want to use it. Nobody is forcing your hand to use these selectors, and I'm sure the ability to select these sort of patterned groups of DOM objects will be useful for somebody; heck, as just one example, how many times did we have to use classes or JS to make a zebra striped table before this?
If you're after flexibility in your mark-up, I'd say that you are indeed better off avoiding these selectors at all costs for just that reason. However, I have used these to great effect on sites that are current, updated regularly, and get a lot of traffic from visitors who support them. Why? Because they give me that little bit of extra sugar on dataset tables, and even on comment listings that I previously would have had to use JS for to avoid the class bloat issue.
As far as I'm concerned, getting style back into the CSS alone and keeping the HTML markup clean is the fundamental issue here, and these do just that. I don't want a HTML file full of a thousand classes just to get my styles the way I want it. Sure, the order of some things may become important by using these, but I'd argue that this is a moot point when changing your HTML markup would ruin any alternative styling attempts anyway if your layout is already complex enough to warrant the usage of nth-child selectors.
If you're the sort of person who wants flexibility over power, even selectors like > are probably no go for you, in which case you'll spend forever writing very long or redundant CSS selectors just to keep everything generic; an approach that is absolutely fine and often necessary, but just not something I personally am willing to try. It seems just as much effort to me to make use of the full power of these new CSS selectors and get great looking layouts at half the bandwidth and markup cost.
Thanks for the article; now it's as clear as gravy...
* required fields