the space combinator

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.

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.

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.