Exploration

Archive: 31 May 2005

The other day I hit a situation that pushed me to come up with a way to simulate the child selector in a way Internet Explorer could understand using two rules. I doubt I’m the first to think of it, but I’d never seen it before, so I thought I’d document the solution here.

The deal was that I had a column of text featuring white background with some black flecks in it. On top of that went some near-black text. All fine, except where the text sat on top of a fleck, which made it next to impossible to read.

To counteract that effect, I decided to set the background of the various descendants of that div to be white, so they’d mask any flecks they were overlapping. Thus I wrote:

#main * {background: #FFF;}

It worked great for about a second. That’s when I realized that I had links in the column, and some of them were sitting inside table rows with a non-white background. The rule I’d just written was giving the links white backgrounds, which had the visual effect of punching holes in the row backgrounds. That was no good.

What I really needed was a way to just set white background on elements that were children of #main. CSS has a child selection combinator (>) but neither version of Internet Explorer supports it. After a few moments’ thought, I realized that I could add a rule that would make transparent the background of any element that was at least a grandchild, but not a child, and it would still work in Explorer.

#main * {background: #FFF;}
#main * * {background: transparent;}

The end result is that there is a way to simulate child selection without actually using the child combinator. The general pattern is to use a normal descendant selection in your first rule, and then “undo” the first rule with a second that has a universal selector in the middle. Suppose you want to boldface any p element that’s a child of a div, but no others. The solution:

div p {font-weight: bold;}
div * p {font-weight: normal;}

It might not be something you use every day, but if it’s needed, there you go.

Update: Lachlan points out that you’ll need to watch out for specificity conflicts when using this technique.