By Alex Walker

Eric’s Universal Child Selector

By Alex Walker

A couple of weeks ago Eric Meyer published a little revelation on mimicking the Universal Child Selector. Although I read it at the time, it probably took a week to sink in to the point where it was of real use to me. I thought I’d look at that here.

In case, you’re not familiar with the child selector, here’s the exec summary.

Although it sounds like some weird ‘sci-fi cloning experiment’, the ‘child selector’ is actually a nifty idea that allows you to set rules that will only be applied when a given element is directly inside a specified other.

In practice, where:

‘div#box p {…}’ effects every P anywhere inside a DIV called ‘#box’

‘div#box>p {…}’ effects only the P’s one level inside the DIV called ‘#box’.

Now, this would be pretty handy, if it wasn’t for the fact Internet Explorer completely and utterly ignores it. As a consequence, the child selector has generally only been of limited usefulness — most often used as a hack/filter which allows you to target styles specifically to non-IE browsers.

That was the state of play until a few weeks ago when Eric pointed out you can get a rough equivalent of the child selector by using a combination of rules that IE does recognize.

Let’s look at a typical situation where it comes in handy.

Take a typical two-column layout like this.

To begin with, I (like many others) usually prefer to get all browsers ‘marching in-step’ by over-riding all their ‘factory-set’ margins and paddings. Using the universal selector (‘*’), that’s fairly effortless.

body * {margin:0 padding:0}

Of course, now all my content wll be squashed uncomfortably against the edges of my major structural DIV’s. However, solving that issue with the obvious solution — i.e. giving them ‘padding’ — requires the extra complexity of box model hacks and other nasties which I prefer to leave out. Instead if I can add ‘margin’ to the items inside my DIVs, I can duck those issues completely. Something like this might do the trick for all our main DIVs.

#content *, #nav *, #links * {margin:3px 10px 8px 10px}

This works beautifully. At least, it does until we need to place more complex markup inside our DIVs and we start to run into ‘runaway margins’. Since our universal selector has added margin to everything, each table cell, row, list item, definition list and wrapper DIV adds it’s own margin to that of the elements surrounding it, stacking up the margins and giving us a generally sucky result.

Eric’s simple solution gives us an antidote by turning the universal selector on itself, like this:

#nav * * {margin:0}

As you can see in the example, by setting a more specific rule for ‘anything that’s two levels or more inside #nav‘, we’re able to counteract our first rule on all items below the first level (‘#links’ is unfixed for the sake of the demo). Nifty.

So, are there any side effects? Not really, although the true child selector works without having any effect at all on the elements below it — Eric’s solution means that you’re forcibly setting those elements, killing any inherited styles from higher levels of the hierachy. Not much you can do about that.

Even so, this looks pretty handy to me.

  • Oh man this is really great. I had an issue on IE mac related to this. I wanted to automatically draw a border around child divs, but not affect the grandchild divs. I tried this out and it did the trick.

    I thought I was going to have to do a ton of reworking on the css file. Thanks for giving me some of my time and sanity back.

  • My pleasure, ant1832. It wasn’t the easiest concept to explain, so I’m glad the message got through. :)

  • excellent. I always wondered what the id>element syntax used in the hacks meant.
    And I learnt something new with the * wildcard too.

  • cob

    Very useful. Thank you!

  • Si

    Thats a great technique to future-proof your CSS too. The IE hacks may be fixed on the next launch of IE (emphasis on “may”!) so this saves one of the issues with the box-model hack and we wont have to go back and fix all our old sites that use the hack as and when M$ sort IE out. Good thinking Eric.

  • Yeah this is a great trick.
    I’m using it very often in my code.
    Makes things a lot simplier

  • Rutger

    great stuff! Thanks for explaining this.

  • icky_bu

    wow, learning something nearly every visit to sitepoint :) thanks!

  • Great article!

    Are these techniques still relevant today?

  • funky house

    this will surely help me css hell, become heaven!!

Get the latest in Front-end, once a week, for free.